Skip to content

Commit 1763a23

Browse files
committed
8.1.0
1 parent 11e1b21 commit 1763a23

File tree

10 files changed

+802
-435
lines changed

10 files changed

+802
-435
lines changed

qspy/include/qpc_qs.h

Lines changed: 135 additions & 158 deletions
Large diffs are not rendered by default.

qspy/include/qpc_qs_pkg.h

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
//============================================================================
2-
// QP/C-Spy software tracing target-resident component
2+
// QP/C Real-Time Event Framework (RTEF)
33
//
44
// Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
55
//
66
// Q u a n t u m L e a P s
77
// ------------------------
88
// Modern Embedded Software
99
//
10-
// SPDX-License-Identifier: LicenseRef-QL-commercial
10+
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
1111
//
12-
// This software is licensed under the terms of the Quantum Leaps commercial
13-
// licenses. Please contact Quantum Leaps for more information about the
14-
// available licensing options.
12+
// This software is dual-licensed under the terms of the open-source GNU
13+
// General Public License (GPL) or under the terms of one of the closed-
14+
// source Quantum Leaps commercial licenses.
1515
//
16-
// RESTRICTIONS
17-
// You may NOT :
18-
// (a) redistribute, encumber, sell, rent, lease, sublicense, or otherwise
19-
// transfer rights in this software,
20-
// (b) remove or alter any trademark, logo, copyright or other proprietary
21-
// notices, legends, symbols or labels present in this software,
22-
// (c) plagiarize this software to sidestep the licensing obligations.
16+
// Redistributions in source code must retain this top-level comment block.
17+
// Plagiarizing this software to sidestep the license obligations is illegal.
2318
//
24-
// Quantum Leaps contact information :
19+
// NOTE:
20+
// The GPL does NOT permit the incorporation of this code into proprietary
21+
// programs. Please contact Quantum Leaps for commercial licensing options,
22+
// which expressly supersede the GPL and are designed explicitly for
23+
// closed-source distribution.
24+
//
25+
// Quantum Leaps contact information:
2526
// <www.state-machine.com/licensing>
2627
// <info@state-machine.com>
2728
//============================================================================
@@ -32,7 +33,7 @@
3233
//! @cond INTERNAL
3334

3435
//! QS received record types (RX channel)
35-
enum QSpyRxRecords {
36+
typedef enum {
3637
QS_RX_INFO, //!< query Target info (ver, config, tstamp)
3738
QS_RX_COMMAND, //!< execute a user-defined command in the Target
3839
QS_RX_RESET, //!< reset the Target
@@ -49,18 +50,18 @@ enum QSpyRxRecords {
4950
QS_RX_CURR_OBJ, //!< set the "current-object" in the Target
5051
QS_RX_TEST_CONTINUE, //!< continue a test after QS_TEST_PAUSE()
5152
QS_RX_QUERY_CURR, //!< query the "current object" in the Target
52-
QS_RX_EVENT //!< inject an event to the Target
53-
};
53+
QS_RX_EVENT, //!< inject an event to the Target
54+
} QS_RxRecords;
5455

5556
//----------------------------------------------------------------------------
56-
#define QS_FRAME 0x7EU
57-
#define QS_ESC 0x7DU
58-
#define QS_ESC_XOR 0x20U
59-
#define QS_GOOD_CHKSUM 0xFFU
57+
#define QS_FRAME ((uint8_t)0x7EU)
58+
#define QS_ESC ((uint8_t)0x7DU)
59+
#define QS_ESC_XOR ((uint8_t)0x20U)
60+
#define QS_GOOD_CHKSUM ((uint8_t)0xFFU)
6061

6162
//----------------------------------------------------------------------------
62-
#define QS_BEGIN_PRE(rec_, qsId_) \
63-
if (QS_GLB_CHECK_(rec_) && QS_LOC_CHECK_(qsId_)) { \
63+
#define QS_BEGIN_PRE(rec_, qsId_) \
64+
if (QS_fltCheck_((rec_), (qsId_))) { \
6465
QS_beginRec_((uint_fast8_t)(rec_));
6566
#define QS_END_PRE() QS_endRec_(); }
6667

@@ -71,14 +72,7 @@ enum QSpyRxRecords {
7172
#define QS_U32_PRE(data_) (QS_u32_raw_((uint32_t)(data_)))
7273
#define QS_STR_PRE(msg_) (QS_str_raw_((msg_)))
7374
#define QS_OBJ_PRE(obj_) (QS_obj_raw_(obj_))
74-
75-
#if (!defined Q_SIGNAL_SIZE || (Q_SIGNAL_SIZE == 1U))
76-
#define QS_SIG_PRE(sig_) (QS_u8_raw_((uint8_t)(sig_)))
77-
#elif (Q_SIGNAL_SIZE == 2U)
78-
#define QS_SIG_PRE(sig_) (QS_u16_raw_((uint16_t)(sig_)))
79-
#elif (Q_SIGNAL_SIZE == 4U)
80-
#define QS_SIG_PRE(sig_) (QS_u32_raw_((uint32_t)(sig_)))
81-
#endif
75+
#define QS_SIG_PRE(sig_) (QS_u16_raw_((uint16_t)(sig_)))
8276

8377
#if (!defined QS_FUN_PTR_SIZE || (QS_FUN_PTR_SIZE == 2U))
8478
#define QS_FUN_PRE(fun_) (QS_u16_raw_((uint16_t)(fun_)))
@@ -150,6 +144,8 @@ enum QSpyRxRecords {
150144
++QS_priv_.used; \
151145
}
152146

147+
#define QS_PTR2UNIT_CAST(T_, ptr_) ((T_)(ptr_))
148+
153149
//! @endcond
154150

155151
#endif // QS_PKG_H_

qspy/include/qspy.h

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#ifndef QSPY_H_
1919
#define QSPY_H_
2020

21-
#define QSPY_VER "8.0.4"
21+
#define QSPY_VER "8.1.0"
2222

2323
#ifdef __cplusplus
2424
extern "C" {
@@ -118,7 +118,8 @@ uint32_t QSPY_encode(uint8_t *dstBuf, uint32_t dstSize,
118118
uint8_t const *srcBuf, uint32_t srcBytes);
119119
uint32_t QSPY_encodeResetCmd(uint8_t *dstBuf, uint32_t dstSize);
120120
uint32_t QSPY_encodeInfoCmd (uint8_t *dstBuf, uint32_t dstSize);
121-
uint32_t QSPY_encodeTickCmd (uint8_t *dstBuf, uint32_t dstSize, uint8_t rate);
121+
uint32_t QSPY_encodeTickCmd (uint8_t *dstBuf, uint32_t dstSize,
122+
uint8_t rate);
122123

123124
SigType QSPY_findSig(char const *name, ObjType obj);
124125
KeyType QSPY_findObj(char const *name);
@@ -163,25 +164,16 @@ typedef struct {
163164
int rx_status; // the type of the RX status
164165
} QSPY_LastOutput;
165166

166-
typedef enum {
167-
GRP_ERR,
168-
GRP_INF,
169-
GRP_DIC,
170-
GRP_TST,
171-
GRP_SM,
172-
GRP_AO,
173-
GRP_EQ,
174-
GRP_MP,
175-
GRP_TE,
176-
GRP_QF,
177-
GRP_SC,
178-
GRP_SEM,
179-
GRP_MTX,
180-
GRP_USR
181-
} QSRreRecGroup;
167+
// Record groups (extend enum QS_Groups from qpc_qs.h)
168+
enum QSpyGroups_plus {
169+
QSPY_GRP_ERR,
170+
QSPY_GRP_INF,
171+
QSPY_GRP_DIC,
172+
QSPY_GRP_TST,
173+
};
182174

183175
// returns the "group" of a given QS record-ID
184-
QSRreRecGroup QSPY_getGroup(int recId);
176+
int QSPY_getGroup(int recId);
185177

186178
// last output generated
187179
extern QSPY_LastOutput QSPY_output;

qspy/qspy_info.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#!/usr/bin/env python
2+
3+
#=============================================================================
4+
# qspy_info utility
5+
# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
6+
#
7+
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
8+
#
9+
# This software is dual-licensed under the terms of the open source GNU
10+
# General Public License version 3 (or any later version), or alternatively,
11+
# under the terms of one of the closed source Quantum Leaps commercial
12+
# licenses.
13+
#
14+
# The terms of the open source GNU General Public License version 3
15+
# can be found at: <www.gnu.org/licenses/gpl-3.0>
16+
#
17+
# The terms of the closed source Quantum Leaps commercial licenses
18+
# can be found at: <www.state-machine.com/licensing>
19+
#
20+
# Redistributions in source code must retain this top-level comment block.
21+
# Plagiarizing this software to sidestep the license obligations is illegal.
22+
#
23+
# Contact information:
24+
# <www.state-machine.com>
25+
# <info@state-machine.com>
26+
#=============================================================================
27+
28+
# pylint: disable=missing-module-docstring,
29+
# pylint: disable=missing-class-docstring,
30+
# pylint: disable=missing-function-docstring
31+
# pylint: disable=broad-except
32+
33+
from platform import python_version
34+
35+
import argparse
36+
import socket
37+
import struct
38+
import sys
39+
40+
#=============================================================================
41+
# Helper class for communication with the QSpy front-end
42+
#
43+
class QSpy:
44+
45+
# public class constants
46+
VERSION = 810
47+
TIMEOUT = 1.000 # timeout value [seconds]
48+
49+
# private class variables...
50+
_sock = None
51+
_is_attached = False
52+
_tx_seq = 0
53+
_host_udp = ["localhost", 7701] # list, to be converted to a tuple
54+
_local_port = 0 # let the OS decide the best local port
55+
56+
# packets to QSpy only...
57+
_QSPY_ATTACH = 128
58+
_QSPY_DETACH = 129
59+
_QSPY_SAVE_DICT = 130
60+
_QSPY_TEXT_OUT = 131
61+
_QSPY_BIN_OUT = 132
62+
_QSPY_MATLAB_OUT = 133
63+
_QSPY_SEQUENCE_OUT = 134
64+
_QSPY_CLEAR_SCREEN = 140
65+
_QSPY_SHOW_NOTE = 141
66+
67+
# records directly to the Target...
68+
TO_TRG_INFO = 0
69+
TO_TRG_RESET = 2
70+
71+
@staticmethod
72+
def _init():
73+
# Create socket
74+
QSpy._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
75+
QSpy._sock.settimeout(QSpy.TIMEOUT) # timeout for blocking socket
76+
#bufsize = QSpy._sock.getsockopt(socket.SOL_UDP, socket.SO_RCVBUF)
77+
#print("SO_RCVBUF ", bufsize)
78+
try:
79+
QSpy._sock.bind(("0.0.0.0", QSpy._local_port))
80+
#print("bind: ", ("0.0.0.0", QSpy._local_port))
81+
except Exception:
82+
print("UDP Socket Error"\
83+
"Can't bind the UDP socket\nto the specified local_host")
84+
sys.exit(-1)
85+
return 0
86+
87+
@staticmethod
88+
def _detach():
89+
if QSpy._sock is None:
90+
return
91+
QSpy.send_to(struct.pack("<B", QSpy._QSPY_DETACH))
92+
time.sleep(QUTest.TIMEOUT)
93+
#QSpy._sock.shutdown(socket.SHUT_RDWR)
94+
QSpy._sock.close()
95+
QSpy._sock = None
96+
QSpy._is_attached = False
97+
98+
@staticmethod
99+
def send_to(packet, payload=None):
100+
tx_packet = bytearray([QSpy._tx_seq])
101+
tx_packet.extend(packet)
102+
if payload is not None:
103+
tx_packet.extend(bytes(payload, "utf-8"))
104+
tx_packet.extend(b"\0") # zero-terminate
105+
QSpy._sock.sendto(tx_packet, QSpy._host_udp)
106+
QSpy._tx_seq = (QSpy._tx_seq + 1) & 0xFF
107+
#print("sendTo", QSpy._tx_seq)
108+
109+
#=============================================================================
110+
# main entry point to qspy_info
111+
def main():
112+
# pylint: disable=protected-access
113+
114+
# parse command-line arguments...
115+
parser = argparse.ArgumentParser(
116+
prog="python qspy_info.py",
117+
description="QSPY-info",
118+
epilog="More info: https://www.state-machine.com/qtools/qspy.html#qspy_info")
119+
parser.add_argument('-v', '--version',
120+
action='version',
121+
version=f"QSPY-info {QSpy.VERSION//100}."\
122+
f"{(QSpy.VERSION//10) % 10}.{QSpy.VERSION % 10} "\
123+
f"on Python {python_version()}",
124+
help='Display QSPY-info version')
125+
126+
parser.add_argument('-q', '--qspy', nargs='?', default='', const='',
127+
help="optional qspy host, [:ud_port]")
128+
args = parser.parse_args()
129+
#print(args)
130+
131+
# process command-line argumens...
132+
if args.qspy != '':
133+
qspy_conf = args.qspy.split(":")
134+
if len(qspy_conf) > 0 and not qspy_conf[0] == '':
135+
QSpy._host_udp[0] = qspy_conf[0]
136+
if len(qspy_conf) > 1 and not qspy_conf[1] == '':
137+
QSpy._host_udp[1] = int(qspy_conf[1])
138+
139+
#print("host_udp:", QSpy._host_udp)
140+
#return 0
141+
142+
# convert to immutable tuple
143+
QSpy._host_udp = tuple(QSpy._host_udp)
144+
145+
# init QSpy socket
146+
err = QSpy._init()
147+
if err:
148+
return sys.exit(err)
149+
150+
QSpy.send_to(struct.pack("<B", QSpy.TO_TRG_INFO))
151+
152+
QSpy._detach()
153+
154+
return 0 # report to the caller (e.g., make)
155+
156+
#=============================================================================
157+
if __name__ == "__main__":
158+
print(f"\nQSPY-info "\
159+
f"{QSpy.VERSION//100}.{(QSpy.VERSION//10) % 10}."\
160+
f"{QSpy.VERSION % 10} running on Python {python_version()}")
161+
print("Copyright (c) 2005-2025 Quantum Leaps, www.state-machine.com")
162+
if sys.version_info >= (3,6):
163+
main()
164+
else:
165+
print("\nERROR: QSPY-info requires Python 3.6 or newer")
166+
sys.exit(-1)

0 commit comments

Comments
 (0)