Skip to content

Commit 80c6b31

Browse files
authored
Refactor addressing modes (#98)
* GET_SEGMENT_INFO and GET_PAGE_INFO * Use macros to abstract the addressing mode encoding * Integer limits without floating point format * Send async command responses via the transmit queue * SetRelativeAddrMode1/2 * CANape projects updated * Compatibility with xcp-lite for Rust * Documentation improvements * Workaround for CANape COPY_CAL_PAGE limitations * Workaround CANape handling of EPK segment * GET_DAQ_EVENT_INFO enabled * EPK calibration segment optional
1 parent 05e827b commit 80c6b31

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+3721
-2838
lines changed

.vscode/tasks.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,30 @@
307307
"group": "build",
308308
"detail": "Kill any running XCP demo processes on Raspberry Pi"
309309
},
310+
{
311+
"type": "shell",
312+
"label": "XCPlite: Download executables from Pi",
313+
"command": "rsync",
314+
"args": [
315+
"-avz",
316+
"--include=\"*.out\"",
317+
"--include=\"*.a\"",
318+
"--exclude=\"*\"",
319+
"[email protected]:~/XCPlite-RainerZ/build/",
320+
"./build/"
321+
],
322+
"options": {
323+
"cwd": "${workspaceFolder}"
324+
},
325+
"group": "build",
326+
"presentation": {
327+
"echo": true,
328+
"reveal": "always",
329+
"focus": false,
330+
"panel": "shared"
331+
},
332+
"detail": "Download executable files (*.out, *.a) from Raspberry Pi build directory"
333+
},
310334
],
311335
"version": "2.0.0"
312336
}

README.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,20 @@ The addressing mode is indicated by the address extension:
340340

341341
- Sockets (Linux: socket, ...).
342342

343-
### Known issues and suggestions for improvement
344-
345-
- Initialize RAM (COPY_CAL_PAGE) is executed only on the first calibration segment.
346-
- GET_SEGMENT_MODE is executed multiple times on the last calibration segment before freeze request.
347-
- Address extension of memory segment is ignored by CANape, using 0 for calibration segment relative addressing.
348-
- Request for unique address extension per DAQ list is ignored by CANape (DAQ_KEY_BYTE == DAQ_EXT_DAQ), this forces us to store store the address extension per ODT entry.
343+
### Known issues
344+
345+
- COPY_CAL_PAGE: CANape initialize RAM is executed only on the first calibration segment. Workaround: always copy all segments.
346+
- CANape ignores segment numbers in A2L, if segment numbering starts with 1, SET_CAL_PAGE is executed on segment 0 and 1
347+
- GET_ID 5 (EPK) mode = 0x01 is ignored by CANape. Workaround: always provide EPK via upload.
348+
- CANape executes GET_SEGMENT_MODE multiple times on the last calibration segment before freeze request.
349+
- Address extension of memory segment is ignored by CANape. Workaround: using 0 for calibration segment relative addressing.
350+
- Request for unique address extension per DAQ list is ignored by CANape (DAQ_KEY_BYTE == DAQ_EXT_DAQ). Workaround: Store the address extension per ODT entry.
349351
- CANape < V24 does not support shared axis in typedefs or THIS. axis references.
350-
- Transport Layer counter mutex could be avoided with different counter mode.
351-
- Indicate when polling access is not possible.
352+
- Transport Layer counter mutex could be avoided with alternative counter mode, which is not default in CANape.
353+
- Indicate when polling access is not possible. CANape assumes polling access is always possible.
354+
- Configuration for begin/end atomic calibration user defined XCP commend is not default. Must be set once in a new CANape project to 0x01F1 and 0x02F1.
355+
356+
### Todo
357+
358+
- CANape ignores address extension of loop_histogram in ccp_demo, when saving calibration values to a parameter file
359+
loop_histogram is a CHARACTERISTIC array, but it is in a measurement group

docs/xcplib.md

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
5. [A2l Creator](#5-a2l-creator)
1212
6. [Glossary](#6-glossary)
1313

14-
1514
---
1615

1716
## 1 · Overview
@@ -22,8 +21,8 @@ All functions are *C linkage* and can therefore be consumed directly from C/C++
2221
Key features:
2322

2423
- Single‑instance XCP server (TCP or UDP)
25-
- Lock‑free calibration segments
26-
- Measurement events to capture global, stack and heap data
24+
- Lock‑free calibration parameter segments
25+
- Timestamped measurement events to capture global, stack and heap data
2726
- Optional A2L file meta data and type generation at runtime
2827

2928
---
@@ -40,7 +39,7 @@ Key features:
4039
2. **Set log level (optional)**
4140

4241
```c
43-
XcpSetLogLevel(5); // (1=error, 2=warning, 3=info, 4=debug, 5=trace):
42+
XcpSetLogLevel(3); // (1=error, 2=warning, 3=info, 4=debug (XCP commands), 5=trace)
4443
```
4544
4645
3. **Initialise the XCP core** *once*:
@@ -66,7 +65,7 @@ Key features:
6665
6766
## 3 · API Reference
6867
69-
### 3.0 · Initialisation
68+
### Initialization
7069
7170
#### void XcpInit( bool activate)
7271
@@ -111,10 +110,62 @@ All out‑parameters are *optional* and may be passed as `NULL`.
111110
112111
See function and macro documentation in xcplib.h
113112
113+
---
114+
114115
### 3.3 Events
115116
116117
See function and macro documentation in xcplib.h
117118
119+
---
120+
121+
### 3.4 A2L Generation
122+
123+
#### bool A2lInit(const char *project_name, const char*epk, const uint8_t *address, uint16_t port, bool use_tcp, uint32_t mode_flags)
124+
125+
Initializes the A2L generation system of XCPlite. This function must be called once before any A2L-related macros or API functions are used. It performs the following actions:
126+
127+
- Allocates and initializes all internal data structures and files required for A2L file creation.
128+
- Enables runtime definition of parameters, measurements, type definitions, groups and conversion rules.
129+
130+
**Parameters:**
131+
132+
- `project_name`: Name of the project, used for the A2L and BIN file names.
133+
- `epk`: Optional software version string (EPK) for the A2L file. Pass `NULL` to use the default.
134+
- `address`: Default IPv4 address of the XCP server.
135+
- `port`: Port number of the XCP server.
136+
- `use_tcp`: If `true`, TCP transport is used; if `false`, UDP transport.
137+
- `mode_flags`: Bitwise combination of A2L generation mode flags controlling file creation and runtime behavior:
138+
- `A2L_MODE_WRITE_ALWAYS` (0x01): Always write the A2L file, overwriting any existing file.
139+
- `A2L_MODE_WRITE_ONCE` (0x02): Write the A2L file (.a2l) once after a rebuild; Uses the binary persistence file (.bin) to keep calibration segment and event numbers stable, even if the registration order changes.
140+
- `A2L_MODE_FINALIZE_ON_CONNECT` (0x04): Finalize the A2L file when an XCP client connects, later registrations are not visible to the tool. If not set, the A2L file must be finalized manually.
141+
- `A2L_MODE_AUTO_GROUPS` (0x08): Automatically create groups for measurement events and parameter segments in the A2L file.
142+
143+
#### void A2lFinalize(void)
144+
145+
Finalizes and writes the A2L file to disk. This function should be called when all measurements, parameters, events, and calibration segments have been registered and no further A2L definitions are expected. After finalization, the A2L file becomes visible to XCP tools and cannot be modified further during runtime.
146+
147+
#### void A2lSetXxxAddrMode(...)
148+
149+
XCPlite uses relative memory addressing. There are 4 different addressing modes. When an addressing mode is set, it is valid for all subsequent definitions of parameters and measurement variables.
150+
151+
| Macro | Description |
152+
|------------------------ |---------------------------------------------------------------------------------------------|
153+
| `A2lSetSegmentAddrMode` | Sets segment-relative addressing mode for calibration parameters in a specific segment. |
154+
| `A2lSetAbsoluteAddrMode`| Sets absolute addressing mode for variables in global memory space. |
155+
| `A2lSetStackAddrMode` | Sets stack-relative addressing mode for variables on the stack (relative to frame pointer). |
156+
| `A2lSetRelativeAddrMode`| Sets relative addressing mode for variables relative to a base address (e.g., heap objects or class instances).|
157+
158+
#### void A2lCreateXxxx(...)
159+
160+
All A2L generation macros and functions are not thread safe. It is up to the user to ensure thread safety and to use once-patterns when definitions are called multiple times in nested functions or from different threads.
161+
The functions `A2lLock()` and `A2lUnlock()` may be used to lock sequences of A2L definitions. The macro `A2lOnce` may be used to create a once execution pattern for a block of A2L definitions.
162+
163+
Also note that A2L definitions may be lazy, but the A2L file is finalized when an XCP tool connects (or when `A2lFinalize()` is called). All definitions after that point are ignored and not visible to the tool.
164+
165+
All definitions of instances follow the same principle: Set the addressing mode first. The addressing mode is valid for all following definitions. The examples in the `examples/` folder show various ways how to create A2L artifacts.
166+
167+
---
168+
118169
### 3.5 Miscellaneous Functions
119170
120171
| Function | Purpose |
@@ -134,20 +185,8 @@ See function and macro documentation in xcplib.h
134185
135186
See examples folder and README.md for a short descriptions of the example applications.
136187
137-
## 5 · A2L Creator
138-
139-
All A2l generation macros and functions are not thread safe. It is up to the user to take care for thread safety, as well as for once execution, when definitions are called multiple times in nested functions or from different threads.
140-
The functions A2lLock() and A2lUnlock() may be used to lock sequences of A2L definitions.
141-
The macro A2lOnce may be used to create a once execution pattern for a block of A2L definitions.
142-
143-
Also note that A2L definitions may be lazy, but the A2L file is finalized when a XCP tool connects. All definitions after that point are ignored and not visible to the tool.
144-
145-
All definitions of instances follow the sample principle: Set the addressing mode first. The addressing mode is valid for all following definitions.
146-
The examples in the examples/folder show various way how to create A2L artifacts.
147-
148188
## 6 · Glossary
149189
150-
151190
- **A2L** – ASAM MCD‑2 MC description file (measurement & calibration meta‑data).
152191
- **DAQ** – Data Acquisition (periodic or sporadic transmit of ECU variables).
153192
- **EPK** – Embedded Program Identifier (software version string embedded in the ECU).

docs/xcplib_cfg.md

Lines changed: 3 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ This section describes the configuration parameters in main_cfg.h.
5757
|-----------|-------------|
5858
| `OPTION_ENABLE_DBG_PRINTS` | Enables debug print statements throughout the library |
5959
| `OPTION_DEFAULT_DBG_LEVEL` | Sets default logging level: 1=Error, 2=Warning, 3=Info, 4=Trace, 5=Debug (default: 2) |
60+
| `OPTION_FIXED_DBG_LEVEL` | Sets fixex logging level, for optimization of unused log prints |
6061

6162
## 2 · xcptl_cfg.h
6263

@@ -111,21 +112,8 @@ This section describes the XCP protocol layer configuration parameters in xcp_cf
111112
| `XCP_ADDR_EXT_DYN` | Address extension code for dynamic addressing (default: 0x02) |
112113
| `XCP_ENABLE_ABS_ADDRESSING` | Enables asynchronous absolute addressing mode (not thread safe) |
113114
| `XCP_ADDR_EXT_ABS` | Address extension code for absolute addressing (default: 0x01) |
114-
| `XCP_ENABLE_APP_ADDRESSING` | Enables segment or application-specific addressing mode |
115-
| `XCP_ADDR_EXT_APP` | Address extension for application-specific memory access (default: 0x00) |
116115
| `XCP_ADDR_EXT_SEG` | Address extension for segment relative addressing (must be 0x00) |
117116

118-
### Special Address Extensions
119-
120-
| Parameter | Description |
121-
|-----------|-------------|
122-
| `XCP_ADDR_EXT_EPK` | Address extension for EPK upload memory space (0x00) |
123-
| `XCP_ADDR_EPK` | Base address for EPK memory space (0x80000000) |
124-
| `XCP_ADDR_EXT_A2L` | Address extension for A2L upload memory space (0xFD) |
125-
| `XCP_ADDR_A2l` | Base address for A2L memory space (0x00000000) |
126-
| `XCP_ADDR_EXT_PTR` | Address extension indicating gXcp.MtaPtr is valid (0xFE) |
127-
| `XCP_UNDEFINED_ADDR_EXT` | Undefined address extension marker (0xFF) |
128-
129117
### Protocol Features
130118

131119
| Parameter | Description |
@@ -149,7 +137,7 @@ This section describes the XCP protocol layer configuration parameters in xcp_cf
149137
| `XCP_DAQ_MEM_SIZE` | Static memory allocation for DAQ tables. Each ODT entry needs 5 bytes, each DAQ list 12 bytes, each ODT 8 bytes |
150138
| `XCP_ENABLE_DAQ_RESUME` | Enables DAQ resume mode functionality |
151139
| `XCP_ENABLE_DAQ_EVENT_LIST` | Enables event list management (not needed for Rust xcp-lite) |
152-
| `XCP_ENABLE_DAQ_EVENT_INFO` | Enables XCP_GET_EVENT_INFO command (overrides A2L event information) |
140+
| `XCP_ENABLE_DAQ_EVENT_INFO` | Enables XCP_GET_EVENT_INFO command |
153141
| `XCP_MAX_EVENT_NAME` | Maximum length for event names in characters (default: 15) |
154142

155143
### Calibration Segment Configuration
@@ -166,8 +154,7 @@ This section describes the XCP protocol layer configuration parameters in xcp_cf
166154

167155
| Parameter | Description |
168156
|-----------|-------------|
169-
| `XCP_DAQ_CLOCK_32BIT` | Uses 32-bit timestamps (commented out) |
170-
| `XCP_DAQ_CLOCK_64BIT` | Uses 64-bit timestamps (default) |
157+
| `XCP_DAQ_CLOCK_64BIT` | Uses XCP V1.3 64-bit timestamps (default) |
171158
| `XCP_TIMESTAMP_UNIT` | Timestamp unit (DAQ_TIMESTAMP_UNIT_1US or DAQ_TIMESTAMP_UNIT_1NS) |
172159
| `XCP_TIMESTAMP_TICKS` | Ticks per timestamp unit (default: 1) |
173160
| `XCP_ENABLE_PTP` | Enables PTP (Precision Time Protocol) grandmaster clock support |
@@ -212,27 +199,6 @@ The queue implementation can be configured using one of three mutually exclusive
212199
| `CACHE_LINE_SIZE` | Cache line size used to align queue entries and queue header. Set to 128 bytes to accommodate most modern CPU architectures |
213200
| `MAX_ENTRY_SIZE` | Maximum size of a single queue entry, calculated as `XCPTL_MAX_DTO_SIZE + XCPTL_TRANSPORT_LAYER_HEADER_SIZE`. Must be aligned to `XCPTL_PACKET_ALIGNMENT` |
214201

215-
### Performance Testing and Profiling (Development Only)
216-
217-
**Warning**: These parameters have significant performance impact and should NOT be enabled in production builds.
218-
219-
| Parameter | Description |
220-
|-----------|-------------|
221-
| `TEST_ACQUIRE_LOCK_TIMING` | Enables timing measurement for queue acquire operations. Collects statistics on lock acquisition times including maximum, sum, and histogram data |
222-
| `TEST_ACQUIRE_SPIN_COUNT` | Enables spin count statistics for producer acquire operations. Tracks how many spin loops are needed during contention |
223-
| `TEST_CONSUMER_SEQ_LOCK_SPIN_COUNT` | Enables spin count statistics for consumer sequence lock operations. Tracks consumer spinning behavior with sequence locks |
224-
225-
### Profiling Configuration Constants
226-
227-
When profiling is enabled, the following constants control the statistics collection:
228-
229-
| Parameter | Description |
230-
|-----------|-------------|
231-
| `LOCK_TIME_HISTOGRAM_SIZE` | Size of lock time histogram array (default: 100 entries) |
232-
| `LOCK_TIME_HISTOGRAM_STEP` | Step size for lock time measurements (10ns steps) |
233-
| `SPIN_COUNT_HISTOGRAM_SIZE` | Size of spin count histogram for producer statistics (default: 100 entries) |
234-
| `SEQ_LOCK_HISTOGRAM_SIZE` | Size of sequence lock histogram for consumer statistics (default: 200 entries) |
235-
236202
### Queue Runtime Configuration
237203

238204
The queue size is configured at runtime when calling `QueueInit(buffer_size)`. The buffer size determines:
@@ -242,21 +208,3 @@ The queue size is configured at runtime when calling `QueueInit(buffer_size)`. T
242208
- Maximum throughput capacity
243209

244210
**Memory Calculation**: Each queue entry requires `MAX_ENTRY_SIZE` bytes plus alignment overhead. The effective queue size is `buffer_size - MAX_ENTRY_SIZE`.
245-
246-
### Platform Requirements
247-
248-
The 64-bit queue implementation requires:
249-
250-
- 64-bit POSIX platform (Linux or macOS)
251-
- Support for atomic operations
252-
- C11 or later for `stdatomic.h`
253-
254-
On 32-bit platforms or Windows, the system automatically falls back to the 32-bit queue implementation (`xcpQueue32.c`).
255-
256-
### Performance Recommendations
257-
258-
1. **For High Throughput**: Use `QUEUE_MUTEX` if worst-case producer latency is acceptable
259-
2. **For Low Latency**: Use `QUEUE_SEQ_LOCK` but expect higher CPU usage due to spinning
260-
3. **For Balanced Performance**: Use `QUEUE_NO_LOCK` (default) for most applications
261-
4. **Buffer Sizing**: Allocate sufficient buffer size to handle peak data rates with some headroom
262-
5. **Testing**: Always benchmark different configurations with your specific workload patterns

0 commit comments

Comments
 (0)