Fixed bug in QXK activator

7.2.1

7.2.1

7.2.1
This commit is contained in:
MMS 2023-01-11 12:04:40 -05:00
parent 417c334876
commit 009bdb4175
96 changed files with 2300 additions and 1101 deletions

View File

@ -7,7 +7,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = QP/C
PROJECT_NUMBER = 7.2.0
PROJECT_NUMBER = 7.2.1
PROJECT_BRIEF = "Real-Time Embedded Framework"
PROJECT_LOGO = ../../ql-doxygen/images/logo_ql.png
OUTPUT_DIRECTORY =

View File

@ -61,7 +61,7 @@
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
43 6 232 3 75 QActive_publish_@90-164@..\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
@ -90,7 +90,7 @@
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
65 17 378 1 112 QK_activate_@278-389@..\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
@ -102,14 +102,14 @@
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 98 QXK_activate_@321-418@..\src\qxk\qxk.c
12 2 72 1 18 QXK_current@421-438@..\src\qxk\qxk.c
19 5 105 1 26 QXK_contextSw@442-467@..\src\qxk\qxk.c
13 2 104 1 23 QXK_threadExit_@474-496@..\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
81 11 724 2 138 QXMutex_lock@89-226@..\src\qxk\qxk_mutex.c
59 9 502 1 97 QXMutex_tryLock@229-325@..\src\qxk\qxk_mutex.c
78 12 670 1 135 QXMutex_unlock@328-462@..\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
@ -153,15 +153,15 @@ NLOC Avg.NLOC AvgCCN Avg.token function_cnt file
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
115 21.2 4.4 123.8 5 ..\src\qf\qf_ps.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
190 22.8 5.0 128.6 8 ..\src\qk\qk.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
235 57.0 8.5 490.0 4 ..\src\qxk\qxk_mutex.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
@ -170,5 +170,5 @@ No thresholds exceeded (cyclomatic_complexity > 20 or length > 500 or nloc > 100
==========================================================================================
Total nloc Avg.NLOC AvgCCN Avg.token Fun Cnt Warning cnt Fun Rt nloc Rt
------------------------------------------------------------------------------------------
4057 24.5 4.3 151.2 125 0 0.00 0.00
4049 24.4 4.3 150.5 125 0 0.00 0.00
@endcode

View File

@ -6,6 +6,21 @@
@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())

View File

@ -1,11 +1,11 @@
/*****************************************************************************
* Product: Simple Blinky example
* Last Updated for Version: 5.6.5
* Date of the Last Update: 2016-06-03
/*============================================================================
* 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
* ---------------------------
* innovating embedded systems
* Q u a n t u m L e a P s
* ------------------------
* Modern Embedded Software
*
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
*
@ -28,19 +28,18 @@
* along with this program. If not, see <www.gnu.org/licenses/>.
*
* Contact information:
* Web: www.state-machine.com
* <www.state-machine.com/licensing>
* <info@state-machine.com>
*****************************************************************************/
============================================================================*/
#include "qpc.h"
#include "blinky.h"
#include "bsp.h"
#include "blinky.h"
//Q_DEFINE_THIS_FILE
/*..........................................................................*/
typedef struct { /* the Blinky active object */
QActive super; /* inherit QActive */
QTimeEvt timeEvt; /* private time event generator */
} Blinky;
@ -49,9 +48,9 @@ static Blinky Blinky_inst; /* the Blinky active object */
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);
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);
/*..........................................................................*/
void Blinky_ctor(void) {
@ -61,8 +60,15 @@ void Blinky_ctor(void) {
}
/* HSM definition ----------------------------------------------------------*/
QState Blinky_initial(Blinky * const me, QEvt const * const e) {
(void)e; /* avoid compiler warning about unused parameter */
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 */
QTimeEvt_armX(&me->timeEvt, BSP_TICKS_PER_SEC/2U, BSP_TICKS_PER_SEC/2U);

View File

@ -1,13 +1,13 @@
/*****************************************************************************
* Product: simple "Blinky" example
* Last Updated for Version: 5.4.0
* Date of the Last Update: 2015-03-07
/*============================================================================
* 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
* ---------------------------
* innovating embedded systems
* Q u a n t u m L e a P s
* ------------------------
* Modern Embedded Software
*
* Copyright (C) 2005 Quantum Leaps, LLC. state-machine.com.
* Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
*
* This program is open source software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@ -30,9 +30,9 @@
* Contact information:
* <www.state-machine.com/licensing>
* <info@state-machine.com>
*****************************************************************************/
#ifndef BLINKY_H
#define BLINKY_H
============================================================================*/
#ifndef BLINKY_H_
#define BLINKY_H_
enum BlinkySignals {
DUMMY_SIG = Q_USER_SIG,
@ -45,4 +45,4 @@ enum BlinkySignals {
void Blinky_ctor(void);
extern QActive * const AO_Blinky; /* opaque pointer */
#endif /* BLINKY_H */
#endif /* BLINKY_H_ */

View File

@ -0,0 +1,242 @@
##############################################################################
# Product: Makefile for Qube for Windows and POSIX *HOSTS*
# 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 <www.gnu.org/licenses/>.
#
# Contact information:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
#
# examples of invoking this Makefile:
# building configurations: qube
# make
# make 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:
#
PROJECT := qube
#-----------------------------------------------------------------------------
# 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
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
#-----------------------------------------------------------------------------
# project files:
#
# C source files...
C_SRCS := \
blinky.c \
main.c \
bsp_qube.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, 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
#-----------------------------------------------------------------------------
# GNU toolset:
#
# NOTE:
# GNU toolset (MinGW) is included in the QTools collection for Windows, see:
# https://github.com/QuantumLeaps/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
#-----------------------------------------------------------------------------
# only Q_SPY build configuration...
BIN_DIR := $(PROJECT)
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
# 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
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))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
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)
$(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 $@
.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
.PHONY : clean show
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)

View File

@ -0,0 +1,38 @@
#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;
}

View File

@ -0,0 +1,21 @@
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}") = "qube_vs", "qube_vs.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
qube_vs|x86 = qube_vs|x86
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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {15807264-0CD3-4BEB-9F83-9E0F04F034E7}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="qube_vs|Win32">
<Configuration>qube_vs</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8CC465F7-872E-4D03-B93C-1B64858B4E11}</ProjectGuid>
<RootNamespace>qube_vs</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;..\..\..\..\include;..\..\..\..\ports\qube;$(QTOOLS)\qspy\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>Q_SPY;Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>
</ExceptionHandling>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4127</DisableSpecificWarnings>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PreBuildEvent>
<Command>cmd /c "del $(OutDir)qstamp.obj"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\src\qf\qf_actq.c" />
<ClCompile Include="bsp_qube.c" />
<ClCompile Include="..\main.c" />
<ClCompile Include="..\blinky.c" />
<ClCompile Include="..\..\..\..\src\qf\qep_hsm.c" />
<ClCompile Include="..\..\..\..\src\qf\qep_msm.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_defer.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_dyn.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_mem.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_ps.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_qact.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_qeq.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_qmact.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_time.c" />
<ClCompile Include="..\..\..\..\src\qs\qs.c" />
<ClCompile Include="..\..\..\..\src\qs\qstamp.c" />
<ClCompile Include="..\..\..\..\src\qs\qs_64bit.c" />
<ClCompile Include="..\..\..\..\src\qs\qs_fp.c" />
<ClCompile Include="..\..\..\..\ports\qube\qube.c" />
<ClCompile Include="$(QTOOLS)\qspy\source\qspy.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\ports\qube\qep_port.h" />
<ClInclude Include="..\..\..\..\ports\qube\qf_port.h" />
<ClInclude Include="..\..\..\..\ports\qube\qs_port.h" />
<ClInclude Include="qhsmtst.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\blinky.c" />
<ClCompile Include="..\..\..\..\ports\qube\qube.c">
<Filter>qube_vs</Filter>
</ClCompile>
<ClCompile Include="bsp_qube.c" />
<ClCompile Include="$(QTOOLS)\qspy\source\qspy.c" />
<ClCompile Include="..\main.c" />
<ClCompile Include="..\..\..\..\src\qf\qep_hsm.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qep_msm.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_actq.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_defer.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_dyn.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_mem.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_ps.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_qact.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_qeq.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_qmact.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_time.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qs.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qs_64bit.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qs_fp.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qstamp.c">
<Filter>QP</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="blinky.h" />
<ClInclude Include="..\..\..\..\ports\qube\qep_port.h">
<Filter>qube_vs</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\ports\qube\qf_port.h">
<Filter>qube_vs</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\ports\qube\qs_port.h">
<Filter>qube_vs</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="qp">
<UniqueIdentifier>{8a14cc5f-5520-4870-80c8-16a728dd5b06}</UniqueIdentifier>
</Filter>
<Filter Include="qube">
<UniqueIdentifier>{b3b54046-9fb7-4796-b157-31c169faf065}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@ -159,16 +159,16 @@
<Type>0</Type>
<LineNumber>377</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>6704</Address>
<Address>0</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<BreakIfRCount>0</BreakIfRCount>
<Filename>..\bsp.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\dpp_qk\../bsp.c\377</Expression>
<Expression></Expression>
</Bp>
<Bp>
<Number>1</Number>

View File

@ -337,7 +337,7 @@
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>QK_USE_IRQ_NUM=25 QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</Define>
<Define>QK_USE_IRQ_NUM=33,QK_USE_IRQ_HANDLER=FPUEH_IRQHandler</Define>
<Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls>

View File

@ -1,7 +1,7 @@
##############################################################################
# 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
# Last Updated for Version: 7.2.1
# Date of the Last Update: 2023-01-14
#
# Q u a n t u m L e a P s
# ------------------------
@ -138,8 +138,8 @@ LIBS :=
# defines
DEFINES := -DEFM32PG1B200F256GM48=1 \
-DQK_USE_IRQ_NUM=25 \
-DQK_USE_IRQ_HANDLER=CRYPTO_IRQHandler
-DQK_USE_IRQ_NUM=33 \
-DQK_USE_IRQ_HANDLER=FPUEH_IRQHandler
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]

View File

@ -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<Sig=TIMEOUT_SIG,Pool=0,Ref=0>,Que<Free=5,Min=5>
0053772439 Sch-Next Pri=0->3
0053772827 AO-GetL Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>
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<Sig=DONE_SIG,Pool=1,Ref=0>
0053775958 Sch-Lock Ceil=0->6
0053776428 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053777295 Sch-Unlk Ceil=6->0
0053777749 Sch-Next Pri=3->6
0053778131 AO-GetL Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>
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<Sig=EAT_SIG,Pool=1,Ref=0>
0053781750 Sch-Lock Ceil=0->6
0053782202 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053783101 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=3>,Que<Free=5,Min=5>
0053784001 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>,Que<Free=5,Min=5>
0053784901 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=5>,Que<Free=5,Min=5>
0053785801 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=6>,Que<Free=5,Min=5>
0053786701 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=7>,Que<Free=5,Min=5>
0053787560 Sch-Unlk Ceil=6->0
0053787984 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=7>
0053788466 PHILO_STAT 3 eating
0053789030 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053789667 QF-gcA Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053790128 Sch-Next Pri=6->6
0053790504 AO-GetL Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=6>
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<Sig=EAT_SIG,Pool=1,Ref=6>
0053792901 Sch-Next Pri=6->5
0053793273 AO-GetL Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=5>
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<Sig=EAT_SIG,Pool=1,Ref=5>
0053795639 Sch-Next Pri=5->4
0053796011 AO-GetL Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>
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<Sig=EAT_SIG,Pool=1,Ref=4>
0053800804 Sch-Rsme Prio=4->3
0053801202 QF-gc Evt<Sig=DONE_SIG,Pool=1,Ref=1>
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<Sig=EAT_SIG,Pool=1,Ref=3>
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<Sig=EAT_SIG,Pool=1,Ref=3>
0053808867 Sch-Next Pri=3->2
0053809239 AO-GetL Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=2>
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<Sig=EAT_SIG,Pool=1,Ref=2>
0053812054 Sch-Next Pri=2->1
0053812427 AO-GetL Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=1>
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<Sig=EAT_SIG,Pool=1,Ref=1>
0053814781 MP-Put Obj=EvtPool1,Free=10
0053815312 Sch-Idle Pri=1->0

View File

@ -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<Sig=TIMEOUT_SIG,Pool=0,Ref=0>,Que<Free=5,Min=5>
0053772441 Sch-Next Pri=0->3
0053772827 AO-GetL Obj=Philo_inst[2],Evt<Sig=TIMEOUT_SIG,Pool=0,Ref=0>
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<Sig=DONE_SIG,Pool=1,Ref=0>
0053775957 Sch-Lock Ceil=0->2
0053776427 AO-Post Sdr=Philo_inst[2],Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053777293 Sch-Unlk Ceil=2->0
0053777742 Sch-Next Pri=3->6
0053778121 AO-GetL Obj=Table_inst,Evt<Sig=DONE_SIG,Pool=1,Ref=2>
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<Sig=EAT_SIG,Pool=1,Ref=0>
0053781749 Sch-Lock Ceil=0->2
0053782201 AO-Post Sdr=Table_inst,Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=2>,Que<Free=5,Min=5>
0053783100 AO-Post Sdr=Table_inst,Obj=Philo_inst[4],Evt<Sig=EAT_SIG,Pool=1,Ref=3>,Que<Free=5,Min=5>
0053783993 AO-Post Sdr=Table_inst,Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>,Que<Free=5,Min=5>
0053784886 AO-Post Sdr=Table_inst,Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=5>,Que<Free=5,Min=5>
0053785779 AO-Post Sdr=Table_inst,Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=6>,Que<Free=5,Min=5>
0053786672 AO-Post Sdr=Table_inst,Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=7>,Que<Free=5,Min=5>
0053787523 Sch-Unlk Ceil=2->0
0053787943 QF-gcA Evt<Sig=EAT_SIG,Pool=1,Ref=7>
0053788426 PHILO_STAT 3 eating
0053788992 =>Intern Obj=Table_inst,Sig=DONE_SIG,State=Table_serving
0053789639 QF-gcA Evt<Sig=DONE_SIG,Pool=1,Ref=2>
0053790098 Sch-Next Pri=6->6
0053790474 AO-GetL Obj=Table_inst,Evt<Sig=EAT_SIG,Pool=1,Ref=6>
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<Sig=EAT_SIG,Pool=1,Ref=6>
0053792872 Sch-Rsme Prio=6->3
0053793269 QF-gc Evt<Sig=DONE_SIG,Pool=1,Ref=1>
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<Sig=EAT_SIG,Pool=1,Ref=5>
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<Sig=EAT_SIG,Pool=1,Ref=5>
0053800951 Sch-Next Pri=5->4
0053801324 AO-GetL Obj=Philo_inst[3],Evt<Sig=EAT_SIG,Pool=1,Ref=4>
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<Sig=EAT_SIG,Pool=1,Ref=4>
0053806094 Sch-Next Pri=4->3
0053806470 AO-GetL Obj=Philo_inst[2],Evt<Sig=EAT_SIG,Pool=1,Ref=3>
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<Sig=EAT_SIG,Pool=1,Ref=3>
0053808855 Sch-Next Pri=3->2
0053809228 AO-GetL Obj=Philo_inst[1],Evt<Sig=EAT_SIG,Pool=1,Ref=2>
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<Sig=EAT_SIG,Pool=1,Ref=2>
0053812037 Sch-Next Pri=2->1
0053812413 AO-GetL Obj=Philo_inst[0],Evt<Sig=EAT_SIG,Pool=1,Ref=1>
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<Sig=EAT_SIG,Pool=1,Ref=1>
0053814766 MP-Put Obj=EvtPool1,Free=10
0053815296 Sch-Idle Pri=1->0

View File

@ -215,8 +215,8 @@
<option>
<name>CCDefines</name>
<state>EFM32PG1B200F256GM48</state>
<state>QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
<state>QK_USE_IRQ_NUM=25</state>
<state>QK_USE_IRQ_HANDLER=FPUEH_IRQHandler</state>
<state>QK_USE_IRQ_NUM=33</state>
</option>
<option>
<name>CCPreprocFile</name>
@ -224,7 +224,7 @@
</option>
<option>
<name>CCPreprocComments</name>
<state>0</state>
<state>1</state>
</option>
<option>
<name>CCPreprocLine</name>
@ -277,7 +277,7 @@
<option>
<name>CCAllowList</name>
<version>1</version>
<state>11111110</state>
<state>00000000</state>
</option>
<option>
<name>CCDebugInfo</name>
@ -358,7 +358,7 @@
</option>
<option>
<name>CCOptLevel</name>
<state>3</state>
<state>1</state>
</option>
<option>
<name>CCOptStrategy</name>
@ -367,7 +367,7 @@
</option>
<option>
<name>CCOptLevelSlave</name>
<state>3</state>
<state>1</state>
</option>
<option>
<name>CCPosIndRopi</name>
@ -3258,255 +3258,6 @@
<name>QP_port</name>
<file>
<name>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar\qk_port.c</name>
<configuration>
<name>Debug</name>
<settings>
<name>ICCARM</name>
<data>
<version>37</version>
<wantNonLocal>0</wantNonLocal>
<debug>1</debug>
<option>
<name>CCOptimizationNoSizeConstraints</name>
<state>0</state>
</option>
<option>
<name>CCDefines</name>
<state>EFM32PG1B200F256GM48</state>
<state>QK_USE_IRQ_NUM=25</state>
<state>QK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
</option>
<option>
<name>CCPreprocFile</name>
<state>0</state>
</option>
<option>
<name>CCPreprocComments</name>
<state>0</state>
</option>
<option>
<name>CCPreprocLine</name>
<state>0</state>
</option>
<option>
<name>CCListCFile</name>
<state>0</state>
</option>
<option>
<name>CCListCMnemonics</name>
<state>0</state>
</option>
<option>
<name>CCListCMessages</name>
<state>0</state>
</option>
<option>
<name>CCListAssFile</name>
<state>0</state>
</option>
<option>
<name>CCListAssSource</name>
<state>0</state>
</option>
<option>
<name>CCEnableRemarks</name>
<state>0</state>
</option>
<option>
<name>CCDiagSuppress</name>
<state>Pa050</state>
</option>
<option>
<name>CCDiagRemark</name>
<state></state>
</option>
<option>
<name>CCDiagWarning</name>
<state></state>
</option>
<option>
<name>CCDiagError</name>
<state></state>
</option>
<option>
<name>CCObjPrefix</name>
<state>1</state>
</option>
<option>
<name>CCAllowList</name>
<version>1</version>
<state>11111110</state>
</option>
<option>
<name>CCDebugInfo</name>
<state>1</state>
</option>
<option>
<name>IEndianMode</name>
<state>1</state>
</option>
<option>
<name>IProcessor</name>
<state>1</state>
</option>
<option>
<name>IExtraOptionsCheck</name>
<state>0</state>
</option>
<option>
<name>IExtraOptions</name>
<state></state>
</option>
<option>
<name>CCLangConformance</name>
<state>0</state>
</option>
<option>
<name>CCSignedPlainChar</name>
<state>1</state>
</option>
<option>
<name>CCRequirePrototypes</name>
<state>1</state>
</option>
<option>
<name>CCDiagWarnAreErr</name>
<state>0</state>
</option>
<option>
<name>CCCompilerRuntimeInfo</name>
<state>0</state>
</option>
<option>
<name>IFpuProcessor</name>
<state>1</state>
</option>
<option>
<name>OutputFile</name>
<state>$FILE_BNAME$.o</state>
</option>
<option>
<name>CCLibConfigHeader</name>
<state>1</state>
</option>
<option>
<name>PreInclude</name>
<state></state>
</option>
<option>
<name>CCIncludePath2</name>
<state>$PROJ_DIR$\..</state>
<state>$PROJ_DIR$\..\..</state>
<state>$PROJ_DIR$\..\..\..\..\..\include</state>
<state>$PROJ_DIR$\..\..\..\..\..\ports\arm-cm\qk\iar</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\CMSIS\Include</state>
<state>$PROJ_DIR$\..\..\..\..\..\3rd_party\efm32pg1b</state>
</option>
<option>
<name>CCStdIncCheck</name>
<state>0</state>
</option>
<option>
<name>CCCodeSection</name>
<state>.text</state>
</option>
<option>
<name>IProcessorMode2</name>
<state>1</state>
</option>
<option>
<name>CCOptLevel</name>
<state>3</state>
</option>
<option>
<name>CCOptStrategy</name>
<version>0</version>
<state>0</state>
</option>
<option>
<name>CCOptLevelSlave</name>
<state>3</state>
</option>
<option>
<name>CCPosIndRopi</name>
<state>0</state>
</option>
<option>
<name>CCPosIndRwpi</name>
<state>0</state>
</option>
<option>
<name>CCPosIndNoDynInit</name>
<state>0</state>
</option>
<option>
<name>IccLang</name>
<state>2</state>
</option>
<option>
<name>IccCDialect</name>
<state>1</state>
</option>
<option>
<name>IccAllowVLA</name>
<state>0</state>
</option>
<option>
<name>IccStaticDestr</name>
<state>1</state>
</option>
<option>
<name>IccCppInlineSemantics</name>
<state>1</state>
</option>
<option>
<name>IccCmsis</name>
<state>1</state>
</option>
<option>
<name>IccFloatSemantics</name>
<state>0</state>
</option>
<option>
<name>CCNoLiteralPool</name>
<state>0</state>
</option>
<option>
<name>CCOptStrategySlave</name>
<version>0</version>
<state>0</state>
</option>
<option>
<name>CCEncSource</name>
<state>0</state>
</option>
<option>
<name>CCEncOutput</name>
<state>0</state>
</option>
<option>
<name>CCEncOutputBom</name>
<state>1</state>
</option>
<option>
<name>CCEncInput</name>
<state>0</state>
</option>
<option>
<name>IccExceptions2</name>
<state>0</state>
</option>
<option>
<name>IccRTTI2</name>
<state>0</state>
</option>
<option>
<name>CCStackProtection</name>
<state>0</state>
</option>
</data>
</settings>
</configuration>
</file>
</group>
<group>

View File

@ -75,7 +75,7 @@
<OPTFL>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>0</IsCurrentTarget>
<IsCurrentTarget>1</IsCurrentTarget>
</OPTFL>
<CpuCode>3</CpuCode>
<DebugOpt>
@ -508,7 +508,7 @@
<OPTFL>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>1</IsCurrentTarget>
<IsCurrentTarget>0</IsCurrentTarget>
</OPTFL>
<CpuCode>3</CpuCode>
<DebugOpt>

View File

@ -337,7 +337,7 @@
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler QXK_USE_IRQ_NUM=25</Define>
<Define>QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler QXK_USE_IRQ_NUM=33</Define>
<Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls>
@ -1662,7 +1662,7 @@
<PlainCh>0</PlainCh>
<Ropi>0</Ropi>
<Rwpi>0</Rwpi>
<wLevel>3</wLevel>
<wLevel>2</wLevel>
<uThumb>0</uThumb>
<uSurpInc>1</uSurpInc>
<uC99>1</uC99>
@ -1676,9 +1676,8 @@
<v6WtE>0</v6WtE>
<v6Rtti>0</v6Rtti>
<VariousControls>
<MiscControls></MiscControls>
<Define>Q_SPY QF_ON_CONTEXT_SW QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler QXK_USE_IRQ_NUM=25
</Define>
<MiscControls>-Wno-padded</MiscControls>
<Define>Q_SPY QF_ON_CONTEXT_SW QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler QXK_USE_IRQ_NUM=33</Define>
<Undefine></Undefine>
<IncludePath>..\..;..\..\..\..\..\include;..\..\..\..\..\ports\arm-cm\qxk\armclang;..\..\..\..\..\3rd_party\CMSIS\Include;..\..\..\..\..\3rd_party\efm32pg1b</IncludePath>
</VariousControls>

View File

@ -1,13 +1,13 @@
##############################################################################
# Product: Makefile for QP/C on EMF32-SLSTK3401A, QXK kernel, GNU-ARM
# Last Updated for Version: 7.2.0
# Date of the Last Update: 2022-12-13
# Last Updated for Version: 7.2.1
# Date of the Last Update: 2023-01-14
#
# Q u a n t u m L e a P s
# ------------------------
# Modern Embedded Software
#
# Copyright (C) 2005-2022 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
@ -143,8 +143,8 @@ LIBS :=
# defines
DEFINES := -DEFM32PG1B200F256GM48=1 \
-DQF_ON_CONTEXT_SW \
-DQXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler \
-DQXK_USE_IRQ_NUM=25
-DQXK_USE_IRQ_NUM=33 \
-DQXK_USE_IRQ_HANDLER=FPUEH_IRQHandler
# ARM CPU, ARCH, FPU, and Float-ABI types...
# ARM_CPU: [cortex-m0 | cortex-m0plus | cortex-m1 | cortex-m3 | cortex-m4]

View File

@ -1,7 +1,7 @@
##############################################################################
# Product: Makefile for QP/C on EMF32-SLSTK3401A, QXK kernel, GNU-ARM
# Last Updated for Version: 7.2.0
# Date of the Last Update: 2022-12-13
# Last Updated for Version: 7.2.1
# Date of the Last Update: 2023-01-14
#
# Q u a n t u m L e a P s
# ------------------------
@ -143,8 +143,8 @@ LIBS :=
# defines
DEFINES := -DEFM32PG1B200F256GM48=1 \
-DQF_ON_CONTEXT_SW \
-DQXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler \
-DQXK_USE_IRQ_NUM=25 \
-DQXK_USE_IRQ_NUM=33 \
-DQXK_USE_IRQ_HANDLER=FPUEH_IRQHandler \
-DQ_NASSERT
# ARM CPU, ARCH, FPU, and Float-ABI types...

View File

@ -215,8 +215,8 @@
<option>
<name>CCDefines</name>
<state>EFM32PG1B200F256GM48</state>
<state>QXK_USE_IRQ_HANDLER=CRYPTO_IRQHandler</state>
<state>QXK_USE_IRQ_NUM=25</state>
<state>QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler</state>
<state>QXK_USE_IRQ_NUM=33</state>
<state>QF_ON_CONTEXT_SW</state>
</option>
<option>
@ -2178,7 +2178,7 @@
</option>
<option>
<name>OGLastSavedByProductVersion</name>
<state>8.50.6.28950</state>
<state>9.10.2.39304</state>
</option>
<option>
<name>OGChipSelectEditMenu</name>
@ -2324,6 +2324,8 @@
<name>CCDefines</name>
<state>Q_SPY</state>
<state>EFM32PG1B200F256GM48</state>
<state>QXK_USE_IRQ_HANDLER=FPUEH_IRQHandler</state>
<state>QXK_USE_IRQ_NUM=33</state>
</option>
<option>
<name>CCPreprocFile</name>

View File

@ -117,10 +117,6 @@
<pMon>BIN\lmidk-agdi.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>

View File

@ -0,0 +1,243 @@
##############################################################################
# Product: Makefile for Qube for Windows and POSIX *HOSTS*
# 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 <www.gnu.org/licenses/>.
#
# Contact information:
# <www.state-machine.com/licensing>
# <info@state-machine.com>
##############################################################################
#
# examples of invoking this Makefile:
# building configurations: qube
# make
# make 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:
#
PROJECT := qube
#-----------------------------------------------------------------------------
# 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
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
#-----------------------------------------------------------------------------
# project files:
#
# C source files...
C_SRCS := \
philo.c \
table.c \
main.c \
bsp.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, 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
#-----------------------------------------------------------------------------
# GNU toolset:
#
# NOTE:
# GNU toolset (MinGW) is included in the QTools collection for Windows, see:
# https://github.com/QuantumLeaps/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
#-----------------------------------------------------------------------------
# only Q_SPY build configuration...
BIN_DIR := $(PROJECT)
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
# 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
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))
# create $(BIN_DIR) if it does not exist
ifeq ("$(wildcard $(BIN_DIR))","")
$(shell $(MKDIR) $(BIN_DIR))
endif
#-----------------------------------------------------------------------------
# rules
#
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)
$(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 $@
.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
.PHONY : clean show
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)

View File

@ -0,0 +1,67 @@
#include "qpc.h"
#include "bsp.h"
#include "dpp.h"
//Q_DEFINE_THIS_FILE
enum AppRecords { /* application-specific trace records */
PHILO_STAT = QS_USER,
PAUSED_STAT,
};
static uint32_t l_rnd; /* random seed */
/*..........................................................................*/
void BSP_init(void) {
/* QS dictionaries... */
QS_USR_DICTIONARY(PHILO_STAT);
QS_USR_DICTIONARY(PAUSED_STAT);
/* QS filters... */
QS_GLB_FILTER(QS_ALL_RECORDS);
}
/*..........................................................................*/
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_END()
}
/*..........................................................................*/
void BSP_displayPaused(uint8_t paused) {
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... */
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)
*/
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 */
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;
}

View File

@ -0,0 +1,87 @@
/*****************************************************************************
* 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 <www.gnu.org/licenses/>.
*
* Contact information:
* <www.state-machine.com/licensing>
* <info@state-machine.com>
*****************************************************************************/
#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 */
}

View File

@ -0,0 +1,21 @@
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}") = "qube_vs", "qube_vs.vcxproj", "{8CC465F7-872E-4D03-B93C-1B64858B4E11}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
qube_vs|x86 = qube_vs|x86
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
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {15807264-0CD3-4BEB-9F83-9E0F04F034E7}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="qube_vs|Win32">
<Configuration>qube_vs</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8CC465F7-872E-4D03-B93C-1B64858B4E11}</ProjectGuid>
<RootNamespace>qube_vs</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>NotSet</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='qube_vs|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;..\..\..\..\include;..\..\..\..\ports\qube;$(QTOOLS)\qspy\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>Q_SPY;Q_SPY;WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling>
</ExceptionHandling>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4127</DisableSpecificWarnings>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PreBuildEvent>
<Command>cmd /c "del $(OutDir)qstamp.obj"</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\src\qf\qf_actq.c" />
<ClCompile Include="bsp_qube.c" />
<ClCompile Include="..\main.c" />
<ClCompile Include="..\blinky.c" />
<ClCompile Include="..\..\..\..\src\qf\qep_hsm.c" />
<ClCompile Include="..\..\..\..\src\qf\qep_msm.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_defer.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_dyn.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_mem.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_ps.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_qact.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_qeq.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_qmact.c" />
<ClCompile Include="..\..\..\..\src\qf\qf_time.c" />
<ClCompile Include="..\..\..\..\src\qs\qs.c" />
<ClCompile Include="..\..\..\..\src\qs\qstamp.c" />
<ClCompile Include="..\..\..\..\src\qs\qs_64bit.c" />
<ClCompile Include="..\..\..\..\src\qs\qs_fp.c" />
<ClCompile Include="..\..\..\..\ports\qube\qube.c" />
<ClCompile Include="$(QTOOLS)\qspy\source\qspy.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\ports\qube\qep_port.h" />
<ClInclude Include="..\..\..\..\ports\qube\qf_port.h" />
<ClInclude Include="..\..\..\..\ports\qube\qs_port.h" />
<ClInclude Include="qhsmtst.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\blinky.c" />
<ClCompile Include="..\..\..\..\ports\qube\qube.c">
<Filter>qube_vs</Filter>
</ClCompile>
<ClCompile Include="bsp_qube.c" />
<ClCompile Include="$(QTOOLS)\qspy\source\qspy.c" />
<ClCompile Include="..\main.c" />
<ClCompile Include="..\..\..\..\src\qf\qep_hsm.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qep_msm.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_actq.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_defer.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_dyn.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_mem.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_ps.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_qact.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_qeq.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_qmact.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qf\qf_time.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qs.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qs_64bit.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qs_fp.c">
<Filter>QP</Filter>
</ClCompile>
<ClCompile Include="..\..\..\..\src\qs\qstamp.c">
<Filter>QP</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="blinky.h" />
<ClInclude Include="..\..\..\..\ports\qube\qep_port.h">
<Filter>qube_vs</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\ports\qube\qf_port.h">
<Filter>qube_vs</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\ports\qube\qs_port.h">
<Filter>qube_vs</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="qp">
<UniqueIdentifier>{8a14cc5f-5520-4870-80c8-16a728dd5b06}</UniqueIdentifier>
</Filter>
<Filter Include="qube">
<UniqueIdentifier>{b3b54046-9fb7-4796-b157-31c169faf065}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@ -117,10 +117,6 @@
<pMon>BIN\lmidk-agdi.dll</pMon>
</DebugOpt>
<TargetDriverDllRegistry>
<SetRegEntry>
<Number>0</Number>
<Key>DLGUARM</Key>
</SetRegEntry>
<SetRegEntry>
<Number>0</Number>
<Key>ARMRTXEVENTFLAGS</Key>

View File

@ -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

View File

@ -0,0 +1,6 @@
@setlocal
@set KEILBUILD_ARM=C:\tools\Keil_v5\UV4\UV4.exe
%KEILBUILD_ARM% -j0 -b dpp-qxk.uvprojx -z
@endlocal

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-09-09
* @version Last updated for: @ref qpc_7_1_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C99 compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -1,100 +0,0 @@
Run ID : 221223_203028
Target : build/test_qutest.exe
==================================[Group 1]==================================
test_assert.py
This test group contains tests that intenionally FAIL,
to exercise failure modes of the QUTest system.
[ 1]--------------------------------------------------------------------------
Expected assertion
[ PASS ( 0.1s) ]
[ 2]--------------------------------------------------------------------------
Unexpected assertion (should FAIL!)
@test_assert.py:22
exp: "0000000002 COMMAND CMD_A 0"
got: "0000000002 =ASSERT= Mod=test_qutest,Loc=100"
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ![ FAIL ( 0.2s) ]
[ 3]--------------------------------------------------------------------------
Simple passing test
[ PASS ( 0.1s) ]
[ 4]--------------------------------------------------------------------------
Wrong assertion expectation (should FAIL!)
@test_assert.py:32
exp: "0000000002 =ASSERT= Mod=test_qutest,Loc=200"
got: "0000000002 =ASSERT= Mod=test_qutest,Loc=100"
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ![ FAIL ( 1.1s) ]
[ 5]--------------------------------------------------------------------------
Simple passing test
[ PASS ( 0.1s) ]
==================================[Group 2]==================================
test_command.py
This test group tests the command() command, which
invokes the QS_onCommand() callback inside the target.
[ 6]--------------------------------------------------------------------------
Command
this test invokes command(1,1,1)
[ PASS ( 0.1s) ]
==================================[Group 3]==================================
test_fp.py
[ 7]--------------------------------------------------------------------------
FP output
[ PASS ( 0.1s) ]
==================================[Group 4]==================================
test_last-rec.py
This test group exercises the las_rec() command
[ 8]--------------------------------------------------------------------------
Last-record
params: 123 23456 3456789 -6.022141e+23
[ PASS ( 0.1s) ]
==================================[Group 5]==================================
test_mem-str.py
[ 9]--------------------------------------------------------------------------
MEM/STR
[ PASS ( 0.1s) ]
[10]--------------------------------------------------------------------------
MEM/STR empty string
[ PASS ( 1.1s) ]
==================================[Group 6]==================================
test_peek-poke.py
[11]--------------------------------------------------------------------------
Peek/Poke/Fill uint8_t
[ PASS ( 0.2s) ]
[12]^-------------------------------------------------------------------------
Peek/Poke/Fill uint16_t
[ PASS ( 0.1s) ]
[13]^-------------------------------------------------------------------------
Peek/Poke/Fill uint32_t
[ PASS ( 0.1s) ]
==================================[Group 7]==================================
test_probe.py
[14]--------------------------------------------------------------------------
Single Test Probe
[ PASS ( 0.1s) ]
[15]^-------------------------------------------------------------------------
Multiple Test Probes
[ PASS ( 0.0s) ]
==================================[ SUMMARY ]=================================
Target ID : 221223_185826 (QP-Ver=720)
Log file : ./qutest221223_203028.txt
Groups : 7
Tests : 15
Skipped : 0
FAILED : 2 [ 2 4 ]
==============================[ FAIL ( 10.7s) ]===============================

View File

@ -1,23 +0,0 @@
Run ID : 221223_203444
Target : build/test_qutest.exe
==================================[Group 1]==================================
test_last-rec.py
This test group exercises the las_rec() command
[ 1]--------------------------------------------------------------------------
Last-record
params: 123 23456 3456789 -6.022141e+23
[ PASS ( 0.1s) ]
==================================[ SUMMARY ]=================================
Target ID : 221223_185826 (QP-Ver=720)
Log file : ./qutest221223_203444.txt
Groups : 1
Tests : 1
Skipped : 0
Failed : 0
==============================[ OK ( 1.2s) ]===============================

View File

@ -1,22 +0,0 @@
Run ID : 221223_203503
Target : build/test_qutest.exe
==================================[Group 1]==================================
test_mem-str.py
[ 1]--------------------------------------------------------------------------
MEM/STR
[ PASS ( 0.1s) ]
[ 2]--------------------------------------------------------------------------
MEM/STR empty string
[ PASS ( 1.1s) ]
==================================[ SUMMARY ]=================================
Target ID : 221223_185826 (QP-Ver=720)
Log file : ./qutest221223_203503.txt
Groups : 1
Tests : 2
Skipped : 0
Failed : 0
==============================[ OK ( 2.4s) ]===============================

View File

@ -1,22 +0,0 @@
Run ID : 221223_203512
Target : build/test_qutest.exe
==================================[Group 1]==================================
test_mem-str.py
[ 1]--------------------------------------------------------------------------
MEM/STR
[ PASS ( 0.1s) ]
[ 2]--------------------------------------------------------------------------
MEM/STR empty string
[ PASS ( 1.1s) ]
==================================[ SUMMARY ]=================================
Target ID : 221223_185826 (QP-Ver=720)
Log file : ./qutest221223_203512.txt
Groups : 1
Tests : 2
Skipped : 0
Failed : 0
==============================[ OK ( 2.4s) ]===============================

View File

@ -52,7 +52,7 @@
* major version number, Y is a 1-digit minor version number, and Z is
* a 1-digit release number.
*/
#define QP_VERSION 720U
#define QP_VERSION 721U
/*! The current QP version as a zero terminated string literal.
*
@ -61,10 +61,10 @@
* 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.0"
#define QP_VERSION_STR "7.2.1"
/*! Encrypted current QP release (7.2.0) and date (2023-01-06) */
#define QP_RELEASE 0x76D8998FU
/*! Encrypted current QP release (7.2.1) and date (2023-01-15) */
#define QP_RELEASE 0x76D739FEU
/*==========================================================================*/
/*$declare${glob-types} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/

View File

@ -272,7 +272,7 @@ enum QSpyPre {
QS_MTX_UNLOCK_ATTEMPT,/*!< a mutex unlock was attempted */
/* [81] */
QS_PRE_MAX, /*!< the number of predefined signals */
QS_PRE_MAX /*!< the number of predefined signals */
};
/*${QS::QSpyGroups} ........................................................*/
@ -319,7 +319,7 @@ 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_AP_ID = 96 /*!< offset for Application-specific IDs */
};
/*${QS::QSpyIdGroups} ......................................................*/
@ -331,7 +331,7 @@ enum QSpyIdGroups {
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_AP_IDS = (0x80 + (enum_t)QS_AP_ID) /*!< Application-specific IDs */
};
/*${QS::QSpyFunPtr} ........................................................*/
@ -409,7 +409,7 @@ enum QS_preType {
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_U64_T /*!< unsigned 64-bit integer format */
};
/*${QS::QS-tx::priv_} ......................................................*/
@ -1280,25 +1280,25 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
#endif /* (Q_SIGNAL_SIZE == 1U) */
/*${QS-macros::QS_SIG_DICTIONARY} ..........................................*/
/*! Output signal dictionary record
/*! 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.
*
* Providing a signal 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 names.
* @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 all 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 NULL.
* 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
@ -1307,18 +1307,10 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
* hand, is global (0 `obj_` pointer):
* @include qs_sigDic.c
*
* @note The QSpy log utility must capture the signal dictionary record
* in order to use the human-readable information. You need to connect to
* the target before the dictionary entries have been transmitted.
*
* 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
*
* The following QSpy log example shows the same sequence of records, but
* with dictionary records removed. The human-readable signal names are not
* available.
*/
#define QS_SIG_DICTIONARY(sig_, obj_) \
(QS_sig_dict_pre_((sig_), (obj_), #sig_))
@ -1330,9 +1322,7 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
* An object dictionary record associates the binary address of an object
* in the target's memory with the human-readable name of the object.
*
* Providing an object 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 object names.
* @param[in] obj_ pointer to the object (any object)
*
* The following example shows the definition of object dictionary entry
* for the Table active object:
@ -1349,13 +1339,12 @@ if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qs_id_)) { \
* object element in the target's memory with the human-readable name
* of the object.
*
* Providing a 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 object names.
* @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_objDic.c
* @include qs_objArrDic.c
*/
#define QS_OBJ_ARR_DICTIONARY(obj_, idx_) \
(QS_obj_arr_dict_pre_((obj_), (idx_), #obj_))

View File

@ -669,7 +669,6 @@ bool QXSemaphore_signal(QXSemaphore * const me);
/*${QXK::QXMutex} ..........................................................*/
/*! @brief Blocking Mutex the QXK preemptive kernel
* @class QXMutex
* @extends QActive
*
* @details
* ::QXMutex is a blocking mutual exclusion mechanism that can also apply
@ -704,11 +703,13 @@ bool QXSemaphore_signal(QXSemaphore * const me);
* @include qxk_mutex.c
*/
typedef struct {
/* protected: */
QActive super;
/* private: */
/*! active object used as a placeholder AO for this mutex
* in QActive_registry_[]
*/
QActive ao;
/*! set of extended-threads waiting on this mutex */
QPSet waitSet;
} QXMutex;

View File

@ -23,8 +23,8 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-18
* @version Last updated for: @ref qpc_7_2_0
* @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
@ -102,7 +102,7 @@ void QK_init(void) {
* 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 / 32U] = (1U << (QK_USE_IRQ_NUM % 32U));
NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU));
#endif /*--------- QK IRQ specified */
#if (__ARM_FP != 0) /*--------- if VFP available... */
@ -150,7 +150,7 @@ __asm volatile (
" PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */
#endif /*--------- VFP available */
" MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n"
" CPSID i \n" /* disable interrutps with BASEPRI */
" 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 */
@ -223,9 +223,9 @@ __asm volatile (
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
#else /*--------- use the selected IRQ */
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
" LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n"
" MOVS r1,#1 \n"
" LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
" 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 */

View File

@ -23,8 +23,8 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-18
* @version Last updated for: @ref qpc_7_2_0
* @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
@ -102,7 +102,7 @@ void QK_init(void) {
* 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 / 32U] = (1U << (QK_USE_IRQ_NUM % 32U));
NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU));
#endif /*--------- QK IRQ specified */
#if (__ARM_FP != 0) /*--------- if VFP available... */
@ -155,7 +155,7 @@ __asm volatile (
" PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */
#endif /*--------- VFP available */
" MOV r0,#" STRINGIFY(QF_BASEPRI) "\n"
" CPSID i \n" /* disable interrutps with BASEPRI */
" 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 */
@ -228,9 +228,9 @@ __asm volatile (
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
#else /*--------- use the selected IRQ */
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
" LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n"
" MOV r1,#1 \n"
" LSL r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
" 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 */

View File

@ -23,8 +23,8 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-18
* @version Last updated for: @ref qpc_7_2_0
* @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
@ -70,6 +70,7 @@ void NMI_Handler(void);
* changed by the application-level code.
*/
void QK_init(void) {
#if (__ARM_ARCH != 6) /*--------- if ARMv7-M and higher... */
/* set exception priorities to QF_BASEPRI...
@ -101,7 +102,7 @@ void QK_init(void) {
* 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 / 32U] = (1U << (QK_USE_IRQ_NUM % 32U));
NVIC_EN[QK_USE_IRQ_NUM >> 5U] = (1U << (QK_USE_IRQ_NUM & 0x1FU));
#endif /*--------- QK IRQ specified */
#if (__ARM_FP != 0) /*--------- if VFP available... */
@ -149,7 +150,7 @@ __asm volatile (
" PUSH {r0,lr} \n" /* ... push lr plus stack-aligner */
#endif /*--------- VFP available */
" MOVS r0,#" STRINGIFY(QF_BASEPRI) "\n"
" CPSID i \n" /* disable interrutps with BASEPRI */
" 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 */
@ -222,13 +223,9 @@ __asm volatile (
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
#else /*--------- use the selected IRQ */
" LDR r0,=" STRINGIFY(NVIC_PEND + (QK_USE_IRQ_NUM / 32)) "\n"
" LDR r0,=" STRINGIFY(NVIC_PEND + ((QK_USE_IRQ_NUM >> 5) << 2)) "\n"
" MOVS r1,#1 \n"
/* NOTE: the following IRQ bit calculation should be done simply as
* (QK_USE_IRQ_NUM % 32), but the IAR assembler does not accept it.
* As a workaround the modulo (%) operation is replaced with the following:
*/
" LSLS r1,r1,#" STRINGIFY(QK_USE_IRQ_NUM - (QK_USE_IRQ_NUM/32)*32) "\n"
" 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 */

View File

@ -23,8 +23,8 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-18
* @version Last updated for: @ref qpc_7_2_0
* @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
@ -45,11 +45,11 @@ void QXK_USE_IRQ_HANDLER(void);
void NMI_Handler(void);
#endif
#define SCnSCB_ICTR ((uint32_t volatile *)0xE000E004)
#define SCB_SYSPRI ((uint32_t volatile *)0xE000ED14)
#define NVIC_EN ((uint32_t volatile *)0xE000E100)
#define NVIC_IP ((uint8_t volatile *)0xE000E400)
#define FPU_FPCCR *((uint32_t volatile *)0xE000EF34)
#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
@ -102,7 +102,7 @@ void QXK_init(void) {
* 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 / 32U] = (1U << (QXK_USE_IRQ_NUM % 32U));
NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU));
#endif /*--------- QXK IRQ specified */
#if (__ARM_FP != 0) /*--------- if VFP available... */
@ -537,9 +537,9 @@ __asm volatile (
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
#else /*--------- use the selected IRQ */
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
" LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n"
" MOVS r1,#1 \n"
" LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
" 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 */

View File

@ -23,8 +23,8 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-18
* @version Last updated for: @ref qpc_7_2_0
* @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
@ -102,7 +102,7 @@ void QXK_init(void) {
* 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 / 32U] = (1U << (QXK_USE_IRQ_NUM % 32U));
NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU));
#endif /*--------- QXK IRQ specified */
#if (__ARM_FP != 0) /*--------- if VFP available... */
@ -542,9 +542,9 @@ __asm volatile (
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
#else /*--------- use the selected IRQ */
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
" LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n"
" MOV r1,#1 \n"
" LSL r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM % 32) "\n" /* r1 := IRQ bit */
" 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 */

View File

@ -23,8 +23,8 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-18
* @version Last updated for: @ref qpc_7_2_0
* @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
@ -102,7 +102,7 @@ void QXK_init(void) {
* 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 / 32U] = (1U << (QXK_USE_IRQ_NUM % 32U));
NVIC_EN[QXK_USE_IRQ_NUM >> 5U] = (1U << (QXK_USE_IRQ_NUM & 0x1FU));
#endif /*--------- QXK IRQ specified */
#if (__ARM_FP != 0) /*--------- if VFP available... */
@ -537,13 +537,9 @@ __asm volatile (
" STR r1,[r0] \n" /* ICSR[31] := 1 (pend NMI) */
#else /*--------- use the selected IRQ */
" LDR r0,=" STRINGIFY(NVIC_PEND + (QXK_USE_IRQ_NUM / 32)) "\n"
" LDR r0,=" STRINGIFY(NVIC_PEND + ((QXK_USE_IRQ_NUM >> 5) << 2)) "\n"
" MOVS r1,#1 \n"
/* NOTE: the following IRQ bit calculation should be done simply as
* (QXK_USE_IRQ_NUM % 32), but the IAR assembler does not accept it.
* As a workaround the modulo (%) operation is replaced with the following:
*/
" LSLS r1,r1,#" STRINGIFY(QXK_USE_IRQ_NUM - (QXK_USE_IRQ_NUM/32)*32) "\n"
" 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 */

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C99 compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @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
* @ingroup ports
*/
#ifndef QF_PORT_H
#define QF_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C99 compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C99 compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, GCC-ARM compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @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
* @ingroup ports
*/
#ifndef QF_PORT_H
#define QF_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-10-02
* @version Last updated for: @ref qpc_7_1_2
* @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
* @ingroup ports
*/
#include "qf_port.h"

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @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
* @ingroup ports
*/
#ifndef QK_PORT_H
#define QK_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, GCC-ARM compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, GCC-ARM compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @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
* @ingroup ports
*/
#ifndef QF_PORT_H
#define QF_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @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
* @ingroup ports
*/
#ifndef QV_PORT_H
#define QV_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C11 compiler
* @ingroup qep
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2023-01-04
* @version Last updated for: @ref qpc_7_2.0
* @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
* @ingroup ports
*/
#ifndef QS_PORT_H
#define QS_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-19
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QS/C QUTest port to POSIX
* @ingroup ports
*/
/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */
#define _POSIX_C_SOURCE 200809L

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C11 compiler
* @ingroup qep
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-08-29
* @version Last updated for: @ref qpc_7_1_0
* @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)
* @ingroup ports
*/
/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QS/C port to POSIX
* @ingroup ports
*/
/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */
#define _POSIX_C_SOURCE 200809L

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2023-01-04
* @version Last updated for: @ref qpc_7_2.0
* @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
* @ingroup ports
*/
#ifndef QS_PORT_H
#define QS_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C11 compiler
* @ingroup qep
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-08-29
* @version Last updated for: @ref qpc_7_1_0
* @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)
* @ingroup ports
*/
/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QS/C port to POSIX
* @ingroup ports
*/
/* expose features from the 2008 POSIX standard (IEEE Standard 1003.1-2008) */
#define _POSIX_C_SOURCE 200809L

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2023-01-04
* @version Last updated for: @ref qpc_7_2.0
* @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
* @ingroup ports
*/
#ifndef QS_PORT_H
#define QS_PORT_H

3
ports/qube/README.txt Normal file
View File

@ -0,0 +1,3 @@
"Qube" is an environment to exercise QP active object components.
"Qube" is a simple console-based application that allows developers
to post/publish events to active objects under development.

70
ports/qube/qep_port.h Normal file
View File

@ -0,0 +1,70 @@
/*============================================================================
* 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: <www.gnu.org/licenses/gpl-3.0>
*
* The terms of the closed source Quantum Leaps commercial licenses
* can be found at: <www.state-machine.com/licensing>
*
* Redistributions in source code must retain this top-level comment block.
* Plagiarizing this software to sidestep the license obligations is illegal.
*
* Contact information:
* <www.state-machine.com>
* <info@state-machine.com>
============================================================================*/
/*!
* @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 <stdint.h> /* Exact-width types. WG14/N843 C99 Standard */
#include <stdbool.h> /* 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_ */

91
ports/qube/qf_port.h Normal file
View File

@ -0,0 +1,91 @@
/*============================================================================
* 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: <www.gnu.org/licenses/gpl-3.0>
*
* The terms of the closed source Quantum Leaps commercial licenses
* can be found at: <www.state-machine.com/licensing>
*
* Redistributions in source code must retain this top-level comment block.
* Plagiarizing this software to sidestep the license obligations is illegal.
*
* Contact information:
* <www.state-machine.com>
* <info@state-machine.com>
============================================================================*/
/*!
* @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 */

64
ports/qube/qs_port.h Normal file
View File

@ -0,0 +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: <www.gnu.org/licenses/gpl-3.0>
*
* The terms of the closed source Quantum Leaps commercial licenses
* can be found at: <www.state-machine.com/licensing>
*
* Redistributions in source code must retain this top-level comment block.
* Plagiarizing this software to sidestep the license obligations is illegal.
*
* Contact information:
* <www.state-machine.com>
* <info@state-machine.com>
============================================================================*/
/*!
* @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)
*/
#ifndef QS_PORT_H_
#define QS_PORT_H_
#define QS_CTR_SIZE 4U
#define QS_TIME_SIZE 4U
/* 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 */
#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()
/*============================================================================
* 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_ */

437
ports/qube/qube.c Normal file
View File

@ -0,0 +1,437 @@
/*============================================================================
* 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: <www.gnu.org/licenses/gpl-3.0>
*
* The terms of the closed source Quantum Leaps commercial licenses
* can be found at: <www.state-machine.com/licensing>
*
* Redistributions in source code must retain this top-level comment block.
* Plagiarizing this software to sidestep the license obligations is illegal.
*
* Contact information:
* <www.state-machine.com>
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_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 */
#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 */
#include "qspy.h" /* QSPY parser interface */
#include "safe_std.h" /* portable "safe" <stdio.h>/<string.h> facilities */
#include <stdlib.h> /* for exit() */
Q_DEFINE_THIS_MODULE("qube")
/*..........................................................................*/
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 void parse_input(void);
static void handle_evts(void);
static char const *HELP_STR =
"Commands:\n"
"<Enter> exit\n"
"? help\n"
"help help\n"
"curr <name> set the current AO\n"
"SIG [params] dispatch a given event to the current AO";
/* terminal colors */
#define B_BLUE "\x1b[44m"
#define F_GRAY "\x1b[30;1m"
#define F_YELLOW "\x1b[33m"
#define F_BYELLOW "\x1b[33;1m"
#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) {
//PRINTF_S("Event: \"%s\"(%d) params: %s\n", cmd, (int)sig, params);
if (l_currAO != (QActive *)0) {
QEvt const *e = Qube_onGenEvt(sig, params);
if (e != (QEvt *)0) {
QACTIVE_POST(l_currAO, e, &Qube);
}
else {
FPRINTF_S(stderr, "ERROR: %s\n",
"Event could not be generated");
}
}
else {
FPRINTF_S(stderr, "ERROR: %s\n",
"No current Active Object found");
}
}
else {
FPRINTF_S(stderr, "ERROR: Dictionary for Event-sig=%s not found\n",
cmd);
}
return true;
}
/*..........................................................................*/
static bool cmd_help(char const* cmd, char const* params) {
Q_UNUSED_PAR(cmd);
Q_UNUSED_PAR(params);
PRINTF_S("\n%s", HELP_STR);
return true;
}
/*..........................................................................*/
static bool cmd_curr(char const* cmd, char const* params) {
Q_UNUSED_PAR(cmd);
KeyType key = QSPY_findObj(params);
if (key != KEY_NOT_FOUND) {
l_currAO = (QActive *)((intptr_t)key);
STRNCPY_S(l_currAO_name, sizeof(l_currAO_name), params);
}
else {
FPRINTF_S(stderr,
"ERROR: Dictionary for Active Object '%s' not found\n",
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 */
{ "?", &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 */
/*
* 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 */
break;
}
else {
*cmd = *lin;
}
}
*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' */
for (; (*lin != '\n') && (lin < &l_line[Q_DIM(l_line) - 1U]); ++lin) {
}
*lin = '\0'; /* zero-terminate */
bool ok = false;
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)... */
for (unsigned i = 1U; i < Q_DIM(commands); ++i) {
if (strcmp(commands[i].name, l_cmd) == 0) {
ok = (*commands[i].handler)(l_cmd, params);
break;
}
}
}
if (!ok) {
FPRINTF_S(stderr, "ERROR: command '%s' not recognized\n", l_cmd);
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
*/
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);
}
}
}
/*..........................................................................*/
#if 0
static char const* my_strtok(char* str, char delim) {
static char* next;
char const* token;
if (str != (char*)0) {
next = str;
}
token = next;
if (token != (char*)0) {
char* s = next;
for (;;) {
if (*s == delim) {
*s = '\0';
next = s + 1;
break;
}
else if (*s == '\0') {
next = (char*)0;
break;
}
else {
++s;
}
}
}
return token;
}
#endif
/* QF functions ============================================================*/
void QF_init(void) {
#ifdef _WIN32
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;
QF_bzero(&QActive_registry_[0], sizeof(QActive_registry_));
QF_bzero(&QF_readySet_, sizeof(QF_readySet_));
l_currAO_name[0] = '\0';
fputs(COLOR_APP, stdout);
/* 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_FUN_DICTIONARY(&QActive_post_);
QS_FUN_DICTIONARY(&QActive_postLIFO_);
QS_OBJ_DICTIONARY(&Qube);
/* produce the QS_QF_RUN trace record */
QS_CRIT_STAT_
QS_BEGIN_PRE_(QS_QF_RUN, 0U)
QS_END_PRE_()
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];
break;
}
}
}
/* still not found? */
if (l_currAO != (QActive*)0) {
extern Dictionary QSPY_objDict;
char const* name = Dictionary_get(&QSPY_objDict,
(KeyType)((uintptr_t)l_currAO), (char*)0);
if (name != (char *)0) {
STRNCPY_S(l_currAO_name, sizeof(l_currAO_name), name);
}
}
else {
STRNCPY_S(l_currAO_name, sizeof(l_currAO_name), "?");
PRINTF_S("%s\n", "No current Active Object found");
}
fputs(COLOR_DFLT "\n", stdout);
/* event loop... */
for (;;) {
PRINTF_S("%s>", l_currAO_name);
if (fgets(l_line, sizeof(l_line), stdin) != (char*)0) {
if (l_line[0] == '\n') { /* <Enter>? */
break;
}
parse_input();
fputs(COLOR_APP, stdout);
handle_evts();
fputs(COLOR_DFLT "\n", stdout);
}
}
QF_onCleanup();
return 0; /* return no error */
}
/*--------------------------------------------------------------------------*/
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);
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. */
}
/*..........................................................................*/
#ifdef QF_ACTIVE_STOP
void QActive_stop(QActive* const me) {
QActive_unsubscribeAll(me); /* unsubscribe from all events */
QActive_unregister_(me); /* un-register this active object */
}
#endif /* def QF_ACTIVE_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 */
QS_initBuf(qsBuf, sizeof(qsBuf));
/* 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 */
};
QSPY_config(&config, (QSPY_CustParseFun)0); // no custom parser function
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;
uint8_t const* block = QS_getBlock(&nBytes);
if (block != (uint8_t*)0) {
QSPY_parse(block, nBytes);
}
else {
break;
}
}
}
/*..........................................................................*/
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);
QF_onCleanup();
QS_EXIT();
exit(-1);
}

108
ports/qube/safe_std.h Normal file
View File

@ -0,0 +1,108 @@
/*============================================================================
* 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: <www.gnu.org/licenses/gpl-3.0>
*
* The terms of the closed source Quantum Leaps commercial licenses
* can be found at: <www.state-machine.com/licensing>
*
* Redistributions in source code must retain this top-level comment block.
* Plagiarizing this software to sidestep the license obligations is illegal.
*
* Contact information:
* <www.state-machine.com>
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_1_3
*
* @file
* @brief "safe" <stdio.h> and <string.h> facilities
*/
#ifndef SAFE_STD_H
#define SAFE_STD_H
#include <stdio.h>
#include <string.h>
/* portable "safe" facilities from <stdio.h> and <string.h> ................*/
#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 */

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-06-12
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QEP/C port, generic C99 compiler
* @ingroup ports
*/
#ifndef QEP_PORT_H
#define QEP_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-08-19
* @version Last updated for: @ref qpc_7_1_0
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QF/C, port to ThreadX
* @ingroup ports
*/
#define QP_IMPL /* this is QP implementation */
#include "qf_port.h" /* QF port */

View File

@ -23,11 +23,10 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2021-12-23
* @version Last updated for: @ref qpc_7_0_0
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @ingroup ports
* @brief QEP/C port, generic C99 compiler
*/
#ifndef QEP_PORT_H

View File

@ -23,11 +23,10 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-10-18
* @version Last updated for: @ref qpc_7_1_3
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @ingroup ports
* @brief QF/C port to uC-OS2, generic C99 compiler
*/
#define QP_IMPL /* this is QP implementation */

View File

@ -23,11 +23,10 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2021-12-23
* @version Last updated for: @ref qpc_7_0_0
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @ingroup ports
* @brief QF/C port to uC-OS2, generic C99 compiler
*/
#ifndef QF_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-11-11
* @version Last updated for: @ref qpc_7_1_3
* @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++
* @ingroup ports
*/
#ifndef QF_PORT_H
#define QF_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2023-01-04
* @version Last updated for: @ref qpc_7_2.0
* @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
* @ingroup ports
*/
#ifndef QS_PORT_H
#define QS_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-12-19
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QS/C QUTest port for Win32
* @ingroup ports
*/
#ifndef Q_SPY
#error "Q_SPY must be defined to compile qutest_port.c"

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-08-29
* @version Last updated for: @ref qpc_7_1_0
* @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)
* @ingroup ports
*/
#define QP_IMPL /* this is QP implementation */
#include "qf_port.h" /* QF port */

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-11-03
* @version Last updated for: @ref qpc_7_1_3
* @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)
* @ingroup ports
*/
#ifndef QF_PORT_H
#define QF_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-06-12
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QS/C port for Win32 API
* @ingroup ports
*/
#ifndef Q_SPY
#error "Q_SPY must be defined to compile qs_port.c"

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2023-01-04
* @version Last updated for: @ref qpc_7_2.0
* @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
* @ingroup ports
*/
#ifndef QS_PORT_H
#define QS_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-08-29
* @version Last updated for: @ref qpc_7_1_0
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QF/C port to Win32 API
* @ingroup ports
*/
#define QP_IMPL /* this is QP implementation */
#include "qf_port.h" /* QF port */

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-11-03
* @version Last updated for: @ref qpc_7_1_3
* @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)
* @ingroup ports
*/
#ifndef QF_PORT_H
#define QF_PORT_H

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2022-07-30
* @version Last updated for: @ref qpc_7_0_1
* @date Last updated on: 2023-01-07
* @version Last updated for: @ref qpc_7_2_0
*
* @file
* @brief QS/C port for Win32 API
* @ingroup ports
*/
#ifndef Q_SPY
#error "Q_SPY must be defined to compile qs_port.c"

View File

@ -23,12 +23,11 @@
* <info@state-machine.com>
============================================================================*/
/*!
* @date Last updated on: 2023-01-04
* @version Last updated for: @ref qpc_7_2.0
* @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
* @ingroup ports
*/
#ifndef QS_PORT_H
#define QS_PORT_H

262
qpc.qm
View File

@ -3992,7 +3992,7 @@ QPSet subscrList = QActive_subscrList_[e-&gt;sig];
QF_CRIT_X_();
if (QPSet_notEmpty(&amp;subscrList)) { /* any subscribers? */
/* the highest-prio subscriber */;
/* the highest-prio subscriber */
uint_fast8_t p = QPSet_findMax(&amp;subscrList);
QActive *a = QActive_registry_[p];
QF_SCHED_STAT_
@ -7040,25 +7040,25 @@ if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qs_id_)) { \
</operation>
<!--${QS-macros::QS_SIG_DICTIONARY}-->
<operation name="QS_SIG_DICTIONARY" type="void" visibility="0x03" properties="0x00">
<documentation>/*! Output signal dictionary record
<documentation>/*! 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.
*
* Providing a signal 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 names.
* @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 &quot;global&quot; signals that have the same meaning in all state machines
* For the &quot;global&quot; 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 NULL.
* 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
@ -7067,18 +7067,10 @@ if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qs_id_)) { \
* hand, is global (0 `obj_` pointer):
* @include qs_sigDic.c
*
* @note The QSpy log utility must capture the signal dictionary record
* in order to use the human-readable information. You need to connect to
* the target before the dictionary entries have been transmitted.
*
* 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
*
* The following QSpy log example shows the same sequence of records, but
* with dictionary records removed. The human-readable signal names are not
* available.
*/</documentation>
<!--${QS-macros::QS_SIG_DICTIONAR~::sig_}-->
<parameter name="sig_" type="QSignal"/>
@ -7095,9 +7087,7 @@ if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qs_id_)) { \
* An object dictionary record associates the binary address of an object
* in the target's memory with the human-readable name of the object.
*
* Providing an object 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 object names.
* @param[in] obj_ pointer to the object (any object)
*
* The following example shows the definition of object dictionary entry
* for the Table active object:
@ -7117,13 +7107,12 @@ if (QS_GLB_CHECK_(rec_) &amp;&amp; QS_LOC_CHECK_(qs_id_)) { \
* object element in the target's memory with the human-readable name
* of the object.
*
* Providing a 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 object names.
* @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_objDic.c
* @include qs_objArrDic.c
*/</documentation>
<!--${QS-macros::QS_OBJ_ARR_DICTI~::obj_}-->
<parameter name="obj_" type="void const *"/>
@ -7404,7 +7393,7 @@ QS_END_NOCRIT_PRE_()</code>
QS_MTX_UNLOCK_ATTEMPT,/*!&lt; a mutex unlock was attempted */
/* [81] */
QS_PRE_MAX, /*!&lt; the number of predefined signals */
QS_PRE_MAX /*!&lt; the number of predefined signals */
};</code>
</attribute>
<!--${QS::QSpyGroups}-->
@ -7454,7 +7443,7 @@ QS_END_NOCRIT_PRE_()</code>
QS_AO_ID = 0, /*!&lt; offset for AO priorities */
QS_EP_ID = 64, /*!&lt; offset for event-pool IDs */
QS_EQ_ID = 80, /*!&lt; offset for event-queue IDs */
QS_AP_ID = 96, /*!&lt; offset for Application-specific IDs */
QS_AP_ID = 96 /*!&lt; offset for Application-specific IDs */
};</code>
</attribute>
<!--${QS::QSpyIdGroups}-->
@ -7467,7 +7456,7 @@ QS_END_NOCRIT_PRE_()</code>
QS_AO_IDS = (0x80 + (enum_t)QS_AO_ID), /*!&lt; AO IDs (priorities) */
QS_EP_IDS = (0x80 + (enum_t)QS_EP_ID), /*!&lt; event-pool IDs */
QS_EQ_IDS = (0x80 + (enum_t)QS_EQ_ID), /*!&lt; event-queue IDs */
QS_AP_IDS = (0x80 + (enum_t)QS_AP_ID), /*!&lt; Application-specific IDs */
QS_AP_IDS = (0x80 + (enum_t)QS_AP_ID) /*!&lt; Application-specific IDs */
};</code>
</attribute>
<!--${QS::QSpyFunPtr}-->
@ -7559,7 +7548,7 @@ QS_END_NOCRIT_PRE_()</code>
QS_OBJ_T, /*!&lt; object pointer format */
QS_FUN_T, /*!&lt; function pointer format */
QS_I64_T, /*!&lt; signed 64-bit integer format */
QS_U64_T, /*!&lt; unsigned 64-bit integer format */
QS_U64_T /*!&lt; unsigned 64-bit integer format */
};</code>
</attribute>
<!--${QS::QS-tx::priv_}-->
@ -10721,10 +10710,11 @@ uint8_t pprev = prio_in;
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 = QActive_registry_[p]-&gt;pthre;
QK_attr_.actThre = a-&gt;pthre;
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (p != pprev) { /* changing threads? */
@ -10774,11 +10764,11 @@ do {
p = (uint8_t)QPSet_findMax(&amp;QF_readySet_);
/* is the new priority below the initial preemption-threshold? */
if (p &lt;= (uint_fast8_t)QActive_registry_[prio_in]-&gt;pthre) {
if (p &lt;= QActive_registry_[prio_in]-&gt;pthre) {
p = 0U; /* no activation needed */
}
/* is the AO's priority below the lock preemption-ceiling? */
else if (p &lt;= (uint_fast8_t)QK_attr_.lockCeil) {
else if (p &lt;= QK_attr_.lockCeil) {
p = 0U; /* no activation needed */
}
else {
@ -12206,10 +12196,9 @@ return signaled;</code>
</operation>
</class>
<!--${QXK::QXMutex}-->
<class name="QXMutex" superclass="QF::QActive">
<class name="QXMutex">
<documentation>/*! @brief Blocking Mutex the QXK preemptive kernel
* @class QXMutex
* @extends QActive
*
* @details
* ::QXMutex is a blocking mutual exclusion mechanism that can also apply
@ -12243,6 +12232,12 @@ return signaled;</code>
* in your application.
* @include qxk_mutex.c
*/</documentation>
<!--${QXK::QXMutex::ao}-->
<attribute name="ao" type="QActive" visibility="0x02" properties="0x00">
<documentation>/*! active object used as a placeholder AO for this mutex
* in QActive_registry_[]
*/</documentation>
</attribute>
<!--${QXK::QXMutex::waitSet}-->
<attribute name="waitSet" type="QPSet" visibility="0x02" properties="0x00">
<documentation>/*! set of extended-threads waiting on this mutex */</documentation>
@ -12277,11 +12272,11 @@ return signaled;</code>
<code>/*! @pre preemption-threshold must not be used */
Q_REQUIRE_ID(100, (prioSpec &amp; 0xFF00U) == 0U);
me-&gt;super.prio = (uint8_t)(prioSpec &amp; 0xFFU); /* QF-priority */
me-&gt;super.pthre = 0U; /* preemption-threshold (not used) */
me-&gt;ao.prio = (uint8_t)(prioSpec &amp; 0xFFU); /* QF-priority */
me-&gt;ao.pthre = 0U; /* preemption-threshold (not used) */
if (prioSpec != 0U) { /* priority-ceiling protocol used? */
QActive_register_(&amp;me-&gt;super); /* register this mutex as AO */
QActive_register_(&amp;me-&gt;ao); /* register this mutex as AO */
}</code>
</operation>
<!--${QXK::QXMutex::lock}-->
@ -12320,80 +12315,78 @@ QXThread * const curr = QXK_PTR_CAST_(QXThread*, QXK_attr_.curr);
*/
Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */
&amp;&amp; (curr != (QXThread *)0) /* current thread must be extended */
&amp;&amp; (me-&gt;super.prio &lt;= QF_MAX_ACTIVE)
&amp;&amp; (me-&gt;ao.prio &lt;= QF_MAX_ACTIVE)
&amp;&amp; (curr-&gt;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-&gt;super.prio);
/* is the mutex available? */
bool locked = true; /* assume that the mutex will be locked */
if (me-&gt;super.eQueue.nFree == 0U) {
me-&gt;super.eQueue.nFree = 1U; /* mutex lock nesting */
if (me-&gt;ao.eQueue.nFree == 0U) {
me-&gt;ao.eQueue.nFree = 1U; /* mutex lock nesting */
/*! @pre also: the newly locked mutex must have no holder yet */
Q_REQUIRE_ID(202, me-&gt;super.thread == (void *)0);
Q_REQUIRE_ID(202, me-&gt;ao.thread == (void *)0);
/* set the new mutex holder to the curr thread and
* save the thread's prio/pthre in the mutex
* save the thread's prio in the mutex
* NOTE: reuse the otherwise unused eQueue data member.
*/
me-&gt;super.thread = curr;
me-&gt;super.eQueue.head = (QEQueueCtr)curr-&gt;super.prio;
me-&gt;super.eQueue.tail = (QEQueueCtr)curr-&gt;super.pthre;
me-&gt;ao.thread = curr;
me-&gt;ao.eQueue.head = (QEQueueCtr)curr-&gt;super.prio;
QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr-&gt;super.prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
(uint8_t)me-&gt;super.eQueue.nFree); /* nesting */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.head); /* holder prio */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.nFree); /* nesting */
QS_END_NOCRIT_PRE_()
if (me-&gt;super.prio != 0U) { /* priority-ceiling protocol used? */
if (me-&gt;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-&gt;super.prio &lt; me-&gt;super.prio)
&amp;&amp; (QActive_registry_[me-&gt;super.prio] == &amp;me-&gt;super));
Q_ASSERT_ID(210, (curr-&gt;super.prio &lt; me-&gt;ao.prio)
&amp;&amp; (QActive_registry_[me-&gt;ao.prio] == &amp;me-&gt;ao));
/* remove the thread's original prio from the ready set
* and insert the mutex's prio into the ready set
*/
QPSet_remove(&amp;QF_readySet_, (uint_fast8_t)me-&gt;super.eQueue.head);
QPSet_insert(&amp;QF_readySet_, (uint_fast8_t)me-&gt;super.prio);
QPSet_remove(&amp;QF_readySet_, (uint_fast8_t)me-&gt;ao.eQueue.head);
QPSet_insert(&amp;QF_readySet_, (uint_fast8_t)me-&gt;ao.prio);
/* put the thread into the AO registry in place of the mutex */
QActive_registry_[me-&gt;super.prio] = &amp;curr-&gt;super;
QActive_registry_[me-&gt;ao.prio] = &amp;curr-&gt;super;
/* set thread's prio/pthre to that of the mutex */
curr-&gt;super.prio = me-&gt;super.prio;
curr-&gt;super.pthre = me-&gt;super.pthre;
/* set thread's prio to that of the mutex */
curr-&gt;super.prio = me-&gt;ao.prio;
}
}
/* is the mutex locked by this thread already (nested locking)? */
else if (me-&gt;super.thread == &amp;curr-&gt;super) {
else if (me-&gt;ao.thread == &amp;curr-&gt;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-&gt;super.eQueue.nFree &lt; 0xFFU);
Q_ASSERT_ID(220, me-&gt;ao.eQueue.nFree &lt; 0xFFU);
++me-&gt;super.eQueue.nFree; /* lock one more level */
++me-&gt;ao.eQueue.nFree; /* lock one more level */
QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr-&gt;super.prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
(uint8_t)me-&gt;super.eQueue.nFree); /* nesting */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.head); /* holder prio */
QS_U8_PRE_((uint8_t)me-&gt;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-&gt;super.thread != (void *)0);
Q_ASSERT_ID(230, me-&gt;ao.thread != (void *)0);
if (me-&gt;super.prio != 0U) { /* priority-ceiling protocol used? */
if (me-&gt;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-&gt;super.prio]
== QXK_PTR_CAST_(QActive *, me-&gt;super.thread));
Q_ASSERT_ID(240, QActive_registry_[me-&gt;ao.prio]
== QXK_PTR_CAST_(QActive *, me-&gt;ao.thread));
}
/* remove the curr thread's prio from the ready set (will block)
@ -12410,7 +12403,7 @@ else { /* the mutex is already locked by a different thread */
QS_BEGIN_NOCRIT_PRE_(QS_MTX_BLOCK, curr-&gt;super.prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
QS_2U8_PRE_((uint8_t)me-&gt;ao.eQueue.head, /* holder prio */
curr-&gt;super.prio); /* blocked thread prio */
QS_END_NOCRIT_PRE_()
@ -12478,78 +12471,76 @@ if (curr == (QActive *)0) { /* called from a basic thread? */
*/
Q_REQUIRE_ID(300, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */
&amp;&amp; (curr != (QActive *)0) /* current thread must be valid */
&amp;&amp; (me-&gt;super.prio &lt;= QF_MAX_ACTIVE));
&amp;&amp; (me-&gt;ao.prio &lt;= QF_MAX_ACTIVE));
/*! @pre also: the thread must NOT be holding a scheduler lock. */
Q_REQUIRE_ID(301, QXK_attr_.lockHolder != curr-&gt;prio);
/* is the mutex available? */
if (me-&gt;super.eQueue.nFree == 0U) {
me-&gt;super.eQueue.nFree = 1U; /* mutex lock nesting */
if (me-&gt;ao.eQueue.nFree == 0U) {
me-&gt;ao.eQueue.nFree = 1U; /* mutex lock nesting */
/*! @pre also: the newly locked mutex must have no holder yet */
Q_REQUIRE_ID(302, me-&gt;super.thread == (void *)0);
Q_REQUIRE_ID(302, me-&gt;ao.thread == (void *)0);
/* set the new mutex holder to the curr thread and
* save the thread's prio/pthre in the mutex
* save the thread's prio in the mutex
* NOTE: reuse the otherwise unused eQueue data member.
*/
me-&gt;super.thread = curr;
me-&gt;super.eQueue.head = (QEQueueCtr)curr-&gt;prio;
me-&gt;super.eQueue.tail = (QEQueueCtr)curr-&gt;pthre;
me-&gt;ao.thread = curr;
me-&gt;ao.eQueue.head = (QEQueueCtr)curr-&gt;prio;
QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr-&gt;prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
(uint8_t)me-&gt;super.eQueue.nFree); /* nesting */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.head); /* holder prio */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.nFree); /* nesting */
QS_END_NOCRIT_PRE_()
if (me-&gt;super.prio != 0U) { /* priority-ceiling protocol used? */
if (me-&gt;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-&gt;prio &lt; me-&gt;super.prio)
&amp;&amp; (QActive_registry_[me-&gt;super.prio] == &amp;me-&gt;super));
Q_ASSERT_ID(210, (curr-&gt;prio &lt; me-&gt;ao.prio)
&amp;&amp; (QActive_registry_[me-&gt;ao.prio] == &amp;me-&gt;ao));
/* remove the thread's original prio from the ready set
* and insert the mutex's prio into the ready set
*/
QPSet_remove(&amp;QF_readySet_, (uint_fast8_t)me-&gt;super.eQueue.head);
QPSet_insert(&amp;QF_readySet_, (uint_fast8_t)me-&gt;super.prio);
QPSet_remove(&amp;QF_readySet_, (uint_fast8_t)me-&gt;ao.eQueue.head);
QPSet_insert(&amp;QF_readySet_, (uint_fast8_t)me-&gt;ao.prio);
/* put the thread into the AO registry in place of the mutex */
QActive_registry_[me-&gt;super.prio] = curr;
QActive_registry_[me-&gt;ao.prio] = curr;
/* set thread's prio/pthre to that of the mutex */
curr-&gt;prio = me-&gt;super.prio;
curr-&gt;pthre = me-&gt;super.pthre;
/* set thread's prio to that of the mutex */
curr-&gt;prio = me-&gt;ao.prio;
}
}
/* is the mutex locked by this thread already (nested locking)? */
else if (me-&gt;super.thread == curr) {
else if (me-&gt;ao.thread == curr) {
/* the nesting level must not exceed the specified limit */
Q_ASSERT_ID(320, me-&gt;super.eQueue.nFree &lt; 0xFFU);
Q_ASSERT_ID(320, me-&gt;ao.eQueue.nFree &lt; 0xFFU);
++me-&gt;super.eQueue.nFree; /* lock one more level */
++me-&gt;ao.eQueue.nFree; /* lock one more level */
QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, curr-&gt;prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
(uint8_t)me-&gt;super.eQueue.nFree); /* nesting */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.head); /* holder prio */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.nFree); /* nesting */
QS_END_NOCRIT_PRE_()
}
else { /* the mutex is already locked by a different thread */
if (me-&gt;super.prio != 0U) { /* priority-ceiling protocol used? */
if (me-&gt;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-&gt;super.prio]
== QXK_PTR_CAST_(QActive *, me-&gt;super.thread));
Q_ASSERT_ID(340, QActive_registry_[me-&gt;ao.prio]
== QXK_PTR_CAST_(QActive *, me-&gt;ao.thread));
}
QS_BEGIN_NOCRIT_PRE_(QS_MTX_BLOCK_ATTEMPT, curr-&gt;prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
QS_2U8_PRE_((uint8_t)me-&gt;ao.eQueue.head, /* holder prio */
curr-&gt;prio); /* trying thread prio */
QS_END_NOCRIT_PRE_()
@ -12595,33 +12586,32 @@ Q_REQUIRE_ID(400, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */
&amp;&amp; (curr != (QActive *)0)); /* current thread must be valid */
/*! @pre also: the mutex must be already locked at least once. */
Q_REQUIRE_ID(401, me-&gt;super.eQueue.nFree &gt; 0U);
Q_REQUIRE_ID(401, me-&gt;ao.eQueue.nFree &gt; 0U);
/*! @pre also: the mutex must be held by this thread. */
Q_REQUIRE_ID(402, me-&gt;super.thread == curr);
Q_REQUIRE_ID(402, me-&gt;ao.thread == curr);
/* is this the last nesting level? */
if (me-&gt;super.eQueue.nFree == 1U) {
if (me-&gt;ao.eQueue.nFree == 1U) {
if (me-&gt;super.prio != 0U) { /* priority-ceiling protocol used? */
if (me-&gt;ao.prio != 0U) { /* priority-ceiling protocol used? */
/* restore the holding thread's prio/pthre from the mutex */
curr-&gt;prio = (uint8_t)me-&gt;super.eQueue.head;
curr-&gt;pthre = (uint8_t)me-&gt;super.eQueue.tail;
/* restore the holding thread's prio from the mutex */
curr-&gt;prio = (uint8_t)me-&gt;ao.eQueue.head;
/* put the mutex back into the AO registry */
QActive_registry_[me-&gt;super.prio] = &amp;me-&gt;super;
QActive_registry_[me-&gt;ao.prio] = &amp;me-&gt;ao;
/* remove the mutex' prio from the ready set
* and insert the original thread's priority
*/
QPSet_remove(&amp;QF_readySet_, (uint_fast8_t)me-&gt;super.prio);
QPSet_insert(&amp;QF_readySet_, (uint_fast8_t)me-&gt;super.eQueue.head);
QPSet_remove(&amp;QF_readySet_, (uint_fast8_t)me-&gt;ao.prio);
QPSet_insert(&amp;QF_readySet_, (uint_fast8_t)me-&gt;ao.eQueue.head);
}
QS_BEGIN_NOCRIT_PRE_(QS_MTX_UNLOCK, curr-&gt;prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
QS_2U8_PRE_((uint8_t)me-&gt;ao.eQueue.head, /* holder prio */
0U); /* nesting */
QS_END_NOCRIT_PRE_()
@ -12655,42 +12645,37 @@ if (me-&gt;super.eQueue.nFree == 1U) {
(void)QXThread_teDisarm_(thr);
/* set the new mutex holder to the curr thread and
* save the thread's prio/pthre in the mutex
* save the thread's prio in the mutex
* NOTE: reuse the otherwise unused eQueue data member.
*/
me-&gt;super.thread = thr;
me-&gt;super.eQueue.head = (QEQueueCtr)thr-&gt;super.prio;
me-&gt;super.eQueue.tail = (QEQueueCtr)thr-&gt;super.pthre;
me-&gt;ao.thread = thr;
me-&gt;ao.eQueue.head = (QEQueueCtr)thr-&gt;super.prio;
QS_BEGIN_NOCRIT_PRE_(QS_MTX_LOCK, thr-&gt;super.prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
(uint8_t)me-&gt;super.eQueue.nFree); /* nesting */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.head); /* holder prio */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.nFree); /* nesting */
QS_END_NOCRIT_PRE_()
if (me-&gt;super.prio != 0U) { /* priority-ceiling protocol used? */
if (me-&gt;ao.prio != 0U) { /* priority-ceiling protocol used? */
/* the holder priority must be lower than that of the mutex */
Q_ASSERT_ID(410, thr-&gt;super.prio &lt; me-&gt;super.prio);
/* set thread's preemption-threshold to that of the mutex */
thr-&gt;super.pthre = me-&gt;super.pthre;
Q_ASSERT_ID(410, thr-&gt;super.prio &lt; me-&gt;ao.prio);
/* put the thread into AO registry in place of the mutex */
QActive_registry_[me-&gt;super.prio] = &amp;thr-&gt;super;
QActive_registry_[me-&gt;ao.prio] = &amp;thr-&gt;super;
}
}
else { /* no threads are waiting for this mutex */
me-&gt;super.eQueue.nFree = 0U; /* free up the nesting count */
me-&gt;ao.eQueue.nFree = 0U; /* free up the nesting count */
/* the mutex no longer held by any thread */
me-&gt;super.thread = (void *)0;
me-&gt;super.eQueue.head = 0U;
me-&gt;super.eQueue.tail = 0U;
me-&gt;ao.thread = (void *)0;
me-&gt;ao.eQueue.head = 0U;
if (me-&gt;super.prio != 0U) { /* priority-ceiling protocol used? */
if (me-&gt;ao.prio != 0U) { /* priority-ceiling protocol used? */
/* put the mutex back at the original mutex slot */
QActive_registry_[me-&gt;super.prio] =
QActive_registry_[me-&gt;ao.prio] =
QXK_PTR_CAST_(QActive*, me);
}
}
@ -12701,14 +12686,14 @@ if (me-&gt;super.eQueue.nFree == 1U) {
}
}
else { /* releasing one level of nested mutex lock */
Q_ASSERT_ID(420, me-&gt;super.eQueue.nFree &gt; 0U);
--me-&gt;super.eQueue.nFree; /* unlock one level */
Q_ASSERT_ID(420, me-&gt;ao.eQueue.nFree &gt; 0U);
--me-&gt;ao.eQueue.nFree; /* unlock one level */
QS_BEGIN_NOCRIT_PRE_(QS_MTX_UNLOCK_ATTEMPT, curr-&gt;prio)
QS_TIME_PRE_(); /* timestamp */
QS_OBJ_PRE_(me); /* this mutex */
QS_2U8_PRE_((uint8_t)me-&gt;super.eQueue.head, /* holder prio */
(uint8_t)me-&gt;super.eQueue.nFree); /* nesting */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.head); /* holder prio */
QS_U8_PRE_((uint8_t)me-&gt;ao.eQueue.nFree); /* nesting */
QS_END_NOCRIT_PRE_()
}
QF_CRIT_X_();</code>
@ -12869,22 +12854,20 @@ do {
p = 0U; /* no activation needed */
}
else {
/* find new highest-prio AO ready to run... */
/* find next highest-prio below the lock ceiling */
p = (uint8_t)QPSet_findMax(&amp;QF_readySet_);
next = QActive_registry_[p];
/* next thread must be registered in QF */
Q_ASSERT_ID(710, next != (QActive *)0);
/* is the next priority below the lock-ceiling? */
if (p &lt;= QXK_attr_.lockCeil) {
p = QXK_attr_.lockHolder; /* thread holding lock */
if (p != 0U) {
Q_ASSERT_ID(720, QPSet_hasElement(&amp;QF_readySet_, p));
Q_ASSERT_ID(710, QPSet_hasElement(&amp;QF_readySet_, p));
}
}
/* is the next a basic thread? */
/* 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-&gt;osObject == (void *)0) {
/* is the next priority above the initial priority? */
if (p &gt; QActive_registry_[prio_in]-&gt;prio) {
@ -13280,7 +13263,7 @@ $declare ${DbC}
* major version number, Y is a 1-digit minor version number, and Z is
* a 1-digit release number.
*/
#define QP_VERSION 720U
#define QP_VERSION 721U
/*! The current QP version as a zero terminated string literal.
*
@ -13289,10 +13272,10 @@ $declare ${DbC}
* major version number, Y is a 1-digit minor version number, and Z is
* a 1-digit release number.
*/
#define QP_VERSION_STR &quot;7.2.0&quot;
#define QP_VERSION_STR &quot;7.2.1&quot;
/*! Encrypted current QP release (7.2.0) and date (2023-01-06) */
#define QP_RELEASE 0x76D8998FU
/*! Encrypted current QP release (7.2.1) and date (2023-01-15) */
#define QP_RELEASE 0x76D739FEU
/*==========================================================================*/
$declare ${glob-types}
@ -15016,15 +14999,16 @@ enum {
WAIT4_EVT_SIG,
WAIT4_EVT_LEN,
WAIT4_EVT_PAR,
WAIT4_EVT_FRAME,
WAIT4_EVT_FRAME
#ifdef Q_UTEST
,
WAIT4_TEST_SETUP_FRAME,
WAIT4_TEST_TEARDOWN_FRAME,
WAIT4_TEST_PROBE_DATA,
WAIT4_TEST_PROBE_ADDR,
WAIT4_TEST_PROBE_FRAME,
WAIT4_TEST_CONTINUE_FRAME,
WAIT4_TEST_CONTINUE_FRAME
#endif /* Q_UTEST */
};

View File

@ -127,7 +127,7 @@ void QActive_publish_(
QF_CRIT_X_();
if (QPSet_notEmpty(&subscrList)) { /* any subscribers? */
/* the highest-prio subscriber */;
/* the highest-prio subscriber */
uint_fast8_t p = QPSet_findMax(&subscrList);
QActive *a = QActive_registry_[p];
QF_SCHED_STAT_

View File

@ -292,10 +292,11 @@ void QK_activate_(void) {
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 = QActive_registry_[p]->pthre;
QK_attr_.actThre = a->pthre;
#if (defined QF_ON_CONTEXT_SW) || (defined Q_SPY)
if (p != pprev) { /* changing threads? */
@ -345,11 +346,11 @@ void QK_activate_(void) {
p = (uint8_t)QPSet_findMax(&QF_readySet_);
/* is the new priority below the initial preemption-threshold? */
if (p <= (uint_fast8_t)QActive_registry_[prio_in]->pthre) {
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 <= (uint_fast8_t)QK_attr_.lockCeil) {
else if (p <= QK_attr_.lockCeil) {
p = 0U; /* no activation needed */
}
else {

View File

@ -167,15 +167,16 @@ enum {
WAIT4_EVT_SIG,
WAIT4_EVT_LEN,
WAIT4_EVT_PAR,
WAIT4_EVT_FRAME,
WAIT4_EVT_FRAME
#ifdef Q_UTEST
,
WAIT4_TEST_SETUP_FRAME,
WAIT4_TEST_TEARDOWN_FRAME,
WAIT4_TEST_PROBE_DATA,
WAIT4_TEST_PROBE_ADDR,
WAIT4_TEST_PROBE_FRAME,
WAIT4_TEST_CONTINUE_FRAME,
WAIT4_TEST_CONTINUE_FRAME
#endif /* Q_UTEST */
};

View File

@ -366,22 +366,20 @@ void QXK_activate_(void) {
p = 0U; /* no activation needed */
}
else {
/* find new highest-prio AO ready to run... */
/* find next highest-prio below the lock ceiling */
p = (uint8_t)QPSet_findMax(&QF_readySet_);
next = QActive_registry_[p];
/* next thread must be registered in QF */
Q_ASSERT_ID(710, next != (QActive *)0);
/* is the next priority below the lock-ceiling? */
if (p <= QXK_attr_.lockCeil) {
p = QXK_attr_.lockHolder; /* thread holding lock */
if (p != 0U) {
Q_ASSERT_ID(720, QPSet_hasElement(&QF_readySet_, p));
Q_ASSERT_ID(710, QPSet_hasElement(&QF_readySet_, p));
}
}
/* is the next a basic thread? */
/* 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) {

View File

@ -77,11 +77,11 @@ void QXMutex_init(QXMutex * const me,
/*! @pre preemption-threshold must not be used */
Q_REQUIRE_ID(100, (prioSpec & 0xFF00U) == 0U);
me->super.prio = (uint8_t)(prioSpec & 0xFFU); /* QF-priority */
me->super.pthre = 0U; /* preemption-threshold (not used) */
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->super); /* register this mutex as AO */
QActive_register_(&me->ao); /* register this mutex as AO */
}
}
@ -102,80 +102,78 @@ bool QXMutex_lock(QXMutex * const me,
*/
Q_REQUIRE_ID(200, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */
&& (curr != (QXThread *)0) /* current thread must be extended */
&& (me->super.prio <= QF_MAX_ACTIVE)
&& (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->super.eQueue.nFree == 0U) {
me->super.eQueue.nFree = 1U; /* mutex lock nesting */
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->super.thread == (void *)0);
Q_REQUIRE_ID(202, me->ao.thread == (void *)0);
/* set the new mutex holder to the curr thread and
* save the thread's prio/pthre in the mutex
* save the thread's prio in the mutex
* NOTE: reuse the otherwise unused eQueue data member.
*/
me->super.thread = curr;
me->super.eQueue.head = (QEQueueCtr)curr->super.prio;
me->super.eQueue.tail = (QEQueueCtr)curr->super.pthre;
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_2U8_PRE_((uint8_t)me->super.eQueue.head, /* holder prio */
(uint8_t)me->super.eQueue.nFree); /* nesting */
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->super.prio != 0U) { /* priority-ceiling protocol used? */
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->super.prio)
&& (QActive_registry_[me->super.prio] == &me->super));
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->super.eQueue.head);
QPSet_insert(&QF_readySet_, (uint_fast8_t)me->super.prio);
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->super.prio] = &curr->super;
QActive_registry_[me->ao.prio] = &curr->super;
/* set thread's prio/pthre to that of the mutex */
curr->super.prio = me->super.prio;
curr->super.pthre = me->super.pthre;
/* 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->super.thread == &curr->super) {
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->super.eQueue.nFree < 0xFFU);
Q_ASSERT_ID(220, me->ao.eQueue.nFree < 0xFFU);
++me->super.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_2U8_PRE_((uint8_t)me->super.eQueue.head, /* holder prio */
(uint8_t)me->super.eQueue.nFree); /* nesting */
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->super.thread != (void *)0);
Q_ASSERT_ID(230, me->ao.thread != (void *)0);
if (me->super.prio != 0U) { /* priority-ceiling protocol used? */
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->super.prio]
== QXK_PTR_CAST_(QActive *, me->super.thread));
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)
@ -192,7 +190,7 @@ bool QXMutex_lock(QXMutex * const me,
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->super.eQueue.head, /* holder prio */
QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */
curr->super.prio); /* blocked thread prio */
QS_END_NOCRIT_PRE_()
@ -242,78 +240,76 @@ bool QXMutex_tryLock(QXMutex * const me) {
*/
Q_REQUIRE_ID(300, (!QXK_ISR_CONTEXT_()) /* don't call from an ISR! */
&& (curr != (QActive *)0) /* current thread must be valid */
&& (me->super.prio <= QF_MAX_ACTIVE));
&& (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->super.eQueue.nFree == 0U) {
me->super.eQueue.nFree = 1U; /* mutex lock nesting */
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->super.thread == (void *)0);
Q_REQUIRE_ID(302, me->ao.thread == (void *)0);
/* set the new mutex holder to the curr thread and
* save the thread's prio/pthre in the mutex
* save the thread's prio in the mutex
* NOTE: reuse the otherwise unused eQueue data member.
*/
me->super.thread = curr;
me->super.eQueue.head = (QEQueueCtr)curr->prio;
me->super.eQueue.tail = (QEQueueCtr)curr->pthre;
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_2U8_PRE_((uint8_t)me->super.eQueue.head, /* holder prio */
(uint8_t)me->super.eQueue.nFree); /* nesting */
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->super.prio != 0U) { /* priority-ceiling protocol used? */
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->super.prio)
&& (QActive_registry_[me->super.prio] == &me->super));
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->super.eQueue.head);
QPSet_insert(&QF_readySet_, (uint_fast8_t)me->super.prio);
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->super.prio] = curr;
QActive_registry_[me->ao.prio] = curr;
/* set thread's prio/pthre to that of the mutex */
curr->prio = me->super.prio;
curr->pthre = me->super.pthre;
/* 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->super.thread == curr) {
else if (me->ao.thread == curr) {
/* the nesting level must not exceed the specified limit */
Q_ASSERT_ID(320, me->super.eQueue.nFree < 0xFFU);
Q_ASSERT_ID(320, me->ao.eQueue.nFree < 0xFFU);
++me->super.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_2U8_PRE_((uint8_t)me->super.eQueue.head, /* holder prio */
(uint8_t)me->super.eQueue.nFree); /* nesting */
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->super.prio != 0U) { /* priority-ceiling protocol used? */
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->super.prio]
== QXK_PTR_CAST_(QActive *, me->super.thread));
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->super.eQueue.head, /* holder prio */
QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */
curr->prio); /* trying thread prio */
QS_END_NOCRIT_PRE_()
@ -342,33 +338,32 @@ void QXMutex_unlock(QXMutex * const me) {
&& (curr != (QActive *)0)); /* current thread must be valid */
/*! @pre also: the mutex must be already locked at least once. */
Q_REQUIRE_ID(401, me->super.eQueue.nFree > 0U);
Q_REQUIRE_ID(401, me->ao.eQueue.nFree > 0U);
/*! @pre also: the mutex must be held by this thread. */
Q_REQUIRE_ID(402, me->super.thread == curr);
Q_REQUIRE_ID(402, me->ao.thread == curr);
/* is this the last nesting level? */
if (me->super.eQueue.nFree == 1U) {
if (me->ao.eQueue.nFree == 1U) {
if (me->super.prio != 0U) { /* priority-ceiling protocol used? */
if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */
/* restore the holding thread's prio/pthre from the mutex */
curr->prio = (uint8_t)me->super.eQueue.head;
curr->pthre = (uint8_t)me->super.eQueue.tail;
/* 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->super.prio] = &me->super;
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->super.prio);
QPSet_insert(&QF_readySet_, (uint_fast8_t)me->super.eQueue.head);
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->super.eQueue.head, /* holder prio */
QS_2U8_PRE_((uint8_t)me->ao.eQueue.head, /* holder prio */
0U); /* nesting */
QS_END_NOCRIT_PRE_()
@ -402,42 +397,37 @@ void QXMutex_unlock(QXMutex * const me) {
(void)QXThread_teDisarm_(thr);
/* set the new mutex holder to the curr thread and
* save the thread's prio/pthre in the mutex
* save the thread's prio in the mutex
* NOTE: reuse the otherwise unused eQueue data member.
*/
me->super.thread = thr;
me->super.eQueue.head = (QEQueueCtr)thr->super.prio;
me->super.eQueue.tail = (QEQueueCtr)thr->super.pthre;
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_2U8_PRE_((uint8_t)me->super.eQueue.head, /* holder prio */
(uint8_t)me->super.eQueue.nFree); /* nesting */
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->super.prio != 0U) { /* priority-ceiling protocol used? */
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->super.prio);
/* set thread's preemption-threshold to that of the mutex */
thr->super.pthre = me->super.pthre;
Q_ASSERT_ID(410, thr->super.prio < me->ao.prio);
/* put the thread into AO registry in place of the mutex */
QActive_registry_[me->super.prio] = &thr->super;
QActive_registry_[me->ao.prio] = &thr->super;
}
}
else { /* no threads are waiting for this mutex */
me->super.eQueue.nFree = 0U; /* free up the nesting count */
me->ao.eQueue.nFree = 0U; /* free up the nesting count */
/* the mutex no longer held by any thread */
me->super.thread = (void *)0;
me->super.eQueue.head = 0U;
me->super.eQueue.tail = 0U;
me->ao.thread = (void *)0;
me->ao.eQueue.head = 0U;
if (me->super.prio != 0U) { /* priority-ceiling protocol used? */
if (me->ao.prio != 0U) { /* priority-ceiling protocol used? */
/* put the mutex back at the original mutex slot */
QActive_registry_[me->super.prio] =
QActive_registry_[me->ao.prio] =
QXK_PTR_CAST_(QActive*, me);
}
}
@ -448,14 +438,14 @@ void QXMutex_unlock(QXMutex * const me) {
}
}
else { /* releasing one level of nested mutex lock */
Q_ASSERT_ID(420, me->super.eQueue.nFree > 0U);
--me->super.eQueue.nFree; /* unlock one level */
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_2U8_PRE_((uint8_t)me->super.eQueue.head, /* holder prio */
(uint8_t)me->super.eQueue.nFree); /* nesting */
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_();