1、QP/C框架源代码下载
下载命令(镜像网址+kk):
git clone https://kkgithub.com/QuantumLeaps/qpc --recurse-submodules
git clone https://kkgithub.com/QuantumLeaps/qpc --recurse-submodules --depth 1
2、QPC集成开发环境安装:https://www.state-machine.com/

安装目录详情:

3、创建工程
(1)源码路径:D:\Code\QP_source\qpc

(2)在QP_source下新增blinky文件夹
PS D:\Code\QP_source> ls
目录: D:\Code\QP_source
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2025/7/8 23:10 blinky
d----- 2025/7/7 22:45 qpc
(3)查看 D:\Code\QP_source\qpc 路径下的 cmakeSupport.md 文件
(4)拷贝 D:\Code\QP_source\qpc\3rd_party\cmake 中的 qpc_sdk_import.cmake 至blinky文件夹
拷贝 D:\Code\QP_source\qpc\examples\posix-win32\blinky 中的 blinky.c 至blinky文件夹
(5)创建CMake脚本文件:
# use a recent CMake version
cmake_minimum_required(VERSION 3.23 FATAL_ERROR)
cmake_policy(VERSION 3.23...3.28)
cmake_policy(SET CMP0083 NEW)
cmake_policy(SET CMP0105 NEW)
cmake_policy(SET CMP0116 NEW)
cmake_policy(SET CMP0128 NEW)
# include general project config & import qpc
set(QPC_SDK_PATH ${CMAKE_SOURCE_DIR}/../qpc) # qpc框架源代码路径
# set(QPC_FETCH_FROM_GIT ON)
# set(QPC_FETCH_FROM_GIT_PATH ${CMAKE_SOURCE_DIR}/Source/qpc-sdk)
include(qpc_sdk_import.cmake)
# default image/project name is trafficlight
# Give a special name via -DIMAGE=<image>
# the main project
project(blinky # the name of the project
VERSION "1.0.0"
DESCRIPTION "my 1st qpc project"
LANGUAGES C
)
# the project target(s)
add_executable( $(PROJECT_NAME) blinky.c)
include(${QPC_SDK_PATH}/qpc_sdk_init.cmake)
set(QPC_PROJECT $(PROJECT_NAME))
set(QPC_CFG_KERNEL QV)
set(QPC_CFG_GUI FALSE)
set(QPC_CFG_PORT win32)
qpc_sdk_init()
target_link_libraries($(PROJECT_NAME) PRIVATE qpc)
至此在blinky目录下有这四个文件

(6) 生成构建文件,生成构建文件目录在build文件夹中
PS D:\Code\QP_source\blinky> cmake -B build -G "MinGW Makefiles"
-- qpc_import.cmake starting...
QPC_SDK_PATH is D:/Code/QP_source/qpc
Set QPC_CFG_GUI to ('FALSE') since not specified
Set QPC_CFG_UNIT_TEST to ('OFF') since not specified
Set QPC_CFG_VERBOSE to ('OFF') since not specified
-- Set QPC_CFG_PORT to ('win32')
-- Found port dir - './win32-qv' for port win32, KERNEL qv
-- ========================================================
Configured project qpc for win32
PROJECT_NAME = blinky
TARGET =
IMAGE =
SW_VERSION =
PORT = win32
QPC_CFG_GUI = FALSE
QPC_CFG_UNIT_TEST = OFF
QPC_CFG_KERNEL = QV
QPC_CFG_DEBUG = ON
CMAKE_C_CPPCHECK =
-- ========================================================
-- Configuring done (0.3s)
-- Generating done (0.1s)
-- Build files have been written to: D:/Code/QP_source/blinky/build
(7) 通过 cmake --build build/ 编译生成可执行文件,其中build/表示构建文件所在路径
PS D:\Code\QP_source\blinky> cmake --build build/
[ 6%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qep_hsm.c.obj
[ 12%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qep_msm.c.obj
[ 18%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_act.c.obj
[ 25%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_defer.c.obj
[ 31%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_dyn.c.obj
[ 37%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_ps.c.obj
[ 43%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_qact.c.obj
[ 50%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_qeq.c.obj
[ 56%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_qmact.c.obj
[ 62%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_time.c.obj
[ 68%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_actq.c.obj
[ 75%] Building C object qpc-sdk/CMakeFiles/qpc.dir/src/qf/qf_mem.c.obj
[ 81%] Building C object qpc-sdk/CMakeFiles/qpc.dir/ports/win32-qv/qf_port.c.obj
[ 87%] Linking C static library libqpc.a
[ 87%] Built target qpc
[ 93%] Building C object CMakeFiles/blinky.dir/blinky.c.obj
[100%] Linking C executable blinky.exe
[100%] Built target blinky
(8)执行程序

(9)在Linux环境下编译运行:
① 设置平台为posix

② 文件夹拷贝至ubuntu

③ 在blinky目录下构建,生成build目录,在build目录下可执行文件 blinky, 执行 sudo ./blinky
cmake -B build -G "Unix Makefiles"
cmake --build build/
控制键盘上的LED灯闪烁,而不是仅仅打印 LED ON 和 LED OFF,所以blinky.c文件修改如下:
#include "qpc.h"
#include "safe_std.h" // portable "safe" <stdio.h>/<string.h> facilities
#include <stdlib.h> // for exit()
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define LED_TRIGGER "/sys/class/leds/input1::capslock/trigger"
#define LED_BRIGHTNESS "/sys/class/leds/input1::capslock/brightness"
#define USAGE() fprintf(stderr, "usage:\n %s <on|off>\n %s <trigger> <type>\n", argv[0], argv[0])
// Q_DEFINE_THIS_FILE
#ifdef Q_SPY
#error Simple Blinky Application does not provide Spy build configuration
#endif
enum
{
BSP_TICKS_PER_SEC = 100
};
//..........................................................................
void BSP_ledOff(void)
{
int fd1, fd2;
fd1 = open(LED_TRIGGER, O_RDWR);
if (0 > fd1)
{
perror("open error");
exit(-1);
}
fd2 = open(LED_BRIGHTNESS, O_RDWR);
if (0 > fd2)
{
perror("open error");
exit(-1);
}
write(fd1, "none", 4);
write(fd2, "0", 1);
}
//..........................................................................
void BSP_ledOn(void)
{
int fd1, fd2;
fd1 = open(LED_TRIGGER, O_RDWR);
if (0 > fd1)
{
perror("open error");
exit(-1);
}
fd2 = open(LED_BRIGHTNESS, O_RDWR);
if (0 > fd2)
{
perror("open error");
exit(-1);
}
write(fd1, "none", 4);
write(fd2, "1", 1);
}
//..........................................................................
Q_NORETURN Q_onError(char const *const module, int_t const id)
{
FPRINTF_S(stderr, "ERROR in %s:%d", module, id);
exit(-1);
}
//..........................................................................
void assert_failed(char const *const module, int_t const id); // prototype
void assert_failed(char const *const module, int_t const id)
{
Q_onError(module, id);
}
//..........................................................................
void QF_onStartup(void) {}
//..........................................................................
void QF_onCleanup(void) {}
//..........................................................................
void QF_onClockTick(void)
{
QTIMEEVT_TICK_X(0U, (void *)0); // clock tick processing
}
enum BlinkySignals
{
TIMEOUT_SIG = Q_USER_SIG,
MAX_SIG
};
///============== ask QM to declare the Blinky class ================
//$declare${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${AOs::Blinky} .............................................................
typedef struct Blinky
{
// protected:
QActive super;
// private:
QTimeEvt timeEvt;
// public:
} Blinky;
extern Blinky Blinky_inst;
// public:
// constructor
static void Blinky_ctor(Blinky *const me);
// protected:
static QState Blinky_initial(Blinky *const me, void const *const par);
static QState Blinky_off(Blinky *const me, QEvt const *const e);
static QState Blinky_on(Blinky *const me, QEvt const *const e);
//$enddecl${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
QActive *const AO_Blinky = &Blinky_inst.super;
int main()
{
QF_init(); // initialize the framework
Blinky_ctor(&Blinky_inst); // explicitly call the "constructor"
static QEvt const *blinky_queueSto[10];
QActive_start(AO_Blinky,
1U, // priority
blinky_queueSto, Q_DIM(blinky_queueSto),
(void *)0, 0U, // no stack
(void *)0); // no initialization parameter
return QF_run(); // run the QF application
}
//================ ask QM to define the Blinky class ================
//$skip${QP_VERSION} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// Check for the minimum required QP version
#if (QP_VERSION < 730U) || (QP_VERSION != ((QP_RELEASE ^ 4294967295U) % 0x2710U))
#error qpc version 7.3.0 or higher required
#endif
//$endskip${QP_VERSION} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//$define${AOs::Blinky} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//${AOs::Blinky} .............................................................
Blinky Blinky_inst;
//${AOs::Blinky::ctor} .......................................................
static void Blinky_ctor(Blinky *const me)
{
QActive_ctor(&me->super, Q_STATE_CAST(&Blinky_initial));
QTimeEvt_ctorX(&me->timeEvt, &me->super, TIMEOUT_SIG, 0U);
}
//${AOs::Blinky::SM} .........................................................
static QState Blinky_initial(Blinky *const me, void const *const par)
{
//${AOs::Blinky::SM::initial}
(void)par; // unused parameter
QTimeEvt_armX(&me->timeEvt,
BSP_TICKS_PER_SEC / 2, BSP_TICKS_PER_SEC / 2);
QS_FUN_DICTIONARY(&Blinky_off);
QS_FUN_DICTIONARY(&Blinky_on);
return Q_TRAN(&Blinky_off);
}
//${AOs::Blinky::SM::off} ....................................................
static QState Blinky_off(Blinky *const me, QEvt const *const e)
{
QState status_;
switch (e->sig)
{
//${AOs::Blinky::SM::off}
case Q_ENTRY_SIG:
{
BSP_ledOff();
status_ = Q_HANDLED();
break;
}
//${AOs::Blinky::SM::off::TIMEOUT}
case TIMEOUT_SIG:
{
status_ = Q_TRAN(&Blinky_on);
break;
}
default:
{
status_ = Q_SUPER(&QHsm_top);
break;
}
}
return status_;
}
//${AOs::Blinky::SM::on} .....................................................
static QState Blinky_on(Blinky *const me, QEvt const *const e)
{
QState status_;
switch (e->sig)
{
//${AOs::Blinky::SM::on}
case Q_ENTRY_SIG:
{
BSP_ledOn();
status_ = Q_HANDLED();
break;
}
//${AOs::Blinky::SM::on::TIMEOUT}
case TIMEOUT_SIG:
{
status_ = Q_TRAN(&Blinky_off);
break;
}
default:
{
status_ = Q_SUPER(&QHsm_top);
break;
}
}
return status_;
}
//$enddef${AOs::Blinky} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
QP框架资源下载
浙公网安备 33010602011771号