@alteriom/painlessmesh 1.7.5 → 1.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +11 -0
- package/docs/releases/RELEASE_CHECKLIST_v1.7.5.md +315 -0
- package/docs/releases/RELEASE_PLAN_v1.7.6.md +816 -0
- package/docs/releases/RELEASE_SUMMARY_v1.7.6.md +436 -0
- package/docs/troubleshooting/PAINLESSMESH_V1.7.4_COMPILATION_ISSUES.md +547 -0
- package/library.json +1 -1
- package/library.properties +1 -1
- package/package.json +1 -1
- package/src/painlessmesh/mesh.hpp +0 -11
- package/src/painlessmesh/scheduler_queue.cpp +0 -77
- package/src/painlessmesh/scheduler_queue.hpp +0 -34
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
# painlessMesh v1.7.4 & v1.7.5 Compilation Issues
|
|
2
|
+
|
|
3
|
+
> ## ✅ RESOLVED IN v1.7.6 (October 19, 2025)
|
|
4
|
+
>
|
|
5
|
+
> **The compilation issues described in this document have been fixed in v1.7.6.**
|
|
6
|
+
>
|
|
7
|
+
> **Solution:** Removed `scheduler_queue.hpp` and `scheduler_queue.cpp` files that required disabled `_TASK_THREAD_SAFE` macro.
|
|
8
|
+
>
|
|
9
|
+
> **Action Required:** Upgrade to v1.7.6 immediately if you're on v1.7.4 or v1.7.5.
|
|
10
|
+
>
|
|
11
|
+
> **Details:** See [RELEASE_SUMMARY_v1.7.6.md](../releases/RELEASE_SUMMARY_v1.7.6.md)
|
|
12
|
+
|
|
13
|
+
**Date**: October 19, 2025
|
|
14
|
+
**Affected Versions**: v1.7.4, v1.7.5
|
|
15
|
+
**Resolved Version**: v1.7.6
|
|
16
|
+
**Working Version**: v1.7.2
|
|
17
|
+
**Platform**: ESP32 (espressif32@6.8.1)
|
|
18
|
+
**Framework**: Arduino
|
|
19
|
+
**Project**: Alteriom Firmware
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Executive Summary
|
|
24
|
+
|
|
25
|
+
painlessMesh versions v1.7.4 and v1.7.5, which include FreeRTOS crash fixes, fail to compile with TaskScheduler v4.0.2 due to missing type definitions (`_task_request_t`) in the thread-safe scheduler queue implementation. The issue stems from an incompatibility between the thread-safe mode (`_TASK_THREAD_SAFE`) and the standard TaskScheduler configuration.
|
|
26
|
+
|
|
27
|
+
**Impact**: Cannot upgrade from v1.7.2 to access FreeRTOS crash fixes, leaving devices vulnerable to `vTaskPriorityDisinheritAfterTimeout` assertion failures when sensor nodes connect.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Problem Description
|
|
32
|
+
|
|
33
|
+
### Symptom
|
|
34
|
+
|
|
35
|
+
Compilation fails when building with painlessMesh v1.7.4 or v1.7.5:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:16:49:
|
|
39
|
+
error: '_task_request_t' was not declared in this scope
|
|
40
|
+
tsQueue = xQueueCreate(TS_QUEUE_LEN, sizeof(_task_request_t));
|
|
41
|
+
^~~~~~~~~~~~~~~
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Root Cause
|
|
45
|
+
|
|
46
|
+
The `scheduler_queue.cpp` implementation expects the `_task_request_t` type to be defined by TaskScheduler when `_TASK_THREAD_SAFE` is enabled, but:
|
|
47
|
+
|
|
48
|
+
1. **TaskScheduler v4.0.2** only defines `_task_request_t` when `_TASK_THREAD_SAFE` is enabled **before** including `TaskScheduler.h`
|
|
49
|
+
2. **painlessMesh v1.7.4/v1.7.5** enables `_TASK_THREAD_SAFE` in `painlessTaskOptions.h` but this happens **after** TaskScheduler headers are processed
|
|
50
|
+
3. **Timing Issue**: The macro definition occurs too late in the compilation sequence
|
|
51
|
+
|
|
52
|
+
### What Changed in v1.7.4+
|
|
53
|
+
|
|
54
|
+
painlessMesh v1.7.4 introduced a thread-safe scheduler queue to fix FreeRTOS crashes:
|
|
55
|
+
|
|
56
|
+
**New Files**:
|
|
57
|
+
- `src/painlessmesh/scheduler_queue.hpp`
|
|
58
|
+
- `src/painlessmesh/scheduler_queue.cpp`
|
|
59
|
+
|
|
60
|
+
**Modified Files**:
|
|
61
|
+
- `src/painlessTaskOptions.h` - Added `#define _TASK_THREAD_SAFE` for ESP32
|
|
62
|
+
- `src/painlessmesh/mesh.hpp` - Added queue initialization
|
|
63
|
+
|
|
64
|
+
**Purpose**: Prevent FreeRTOS `vTaskPriorityDisinheritAfterTimeout` assertion failures by using FreeRTOS queues for thread-safe task control.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Compilation Error Details
|
|
69
|
+
|
|
70
|
+
### v1.7.4 Build Attempt (Build 8022)
|
|
71
|
+
|
|
72
|
+
**Command**:
|
|
73
|
+
```bash
|
|
74
|
+
$env:BUILD_NUMBER_OVERRIDE="8022"; docker-compose run --rm alteriom-builder pio run -e universal-gateway
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Error Output**:
|
|
78
|
+
```
|
|
79
|
+
Compiling .pio/build/universal-gateway/lib55b/AlteriomPainlessMesh/painlessmesh/scheduler_queue.cpp.o
|
|
80
|
+
|
|
81
|
+
.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:
|
|
82
|
+
In function 'bool painlessmesh::scheduler::initQueue()':
|
|
83
|
+
|
|
84
|
+
.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:16:49:
|
|
85
|
+
error: '_task_request_t' was not declared in this scope
|
|
86
|
+
tsQueue = xQueueCreate(TS_QUEUE_LEN, sizeof(_task_request_t));
|
|
87
|
+
^~~~~~~~~~~~~~~
|
|
88
|
+
|
|
89
|
+
.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:29:28:
|
|
90
|
+
error: '_task_request_t' was not declared in this scope
|
|
91
|
+
bool _task_enqueue_request(_task_request_t* req) {
|
|
92
|
+
^~~~~~~~~~~~~~~
|
|
93
|
+
|
|
94
|
+
.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:29:45:
|
|
95
|
+
error: 'req' was not declared in this scope
|
|
96
|
+
bool _task_enqueue_request(_task_request_t* req) {
|
|
97
|
+
^~~
|
|
98
|
+
|
|
99
|
+
.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:56:28:
|
|
100
|
+
error: '_task_request_t' was not declared in this scope
|
|
101
|
+
bool _task_dequeue_request(_task_request_t* req) {
|
|
102
|
+
^~~~~~~~~~~~~~~
|
|
103
|
+
|
|
104
|
+
.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:56:45:
|
|
105
|
+
error: 'req' was not declared in this scope
|
|
106
|
+
bool _task_dequeue_request(_task_request_t* req) {
|
|
107
|
+
^~~
|
|
108
|
+
|
|
109
|
+
*** [.pio/build/universal-gateway/lib55b/AlteriomPainlessMesh/painlessmesh/scheduler_queue.cpp.o] Error 1
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### v1.7.5 Build Attempt (Build 8024)
|
|
113
|
+
|
|
114
|
+
**Command**:
|
|
115
|
+
```bash
|
|
116
|
+
$env:BUILD_NUMBER_OVERRIDE="8024"; docker-compose run --rm alteriom-builder pio run -e universal-gateway
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Result**: **IDENTICAL ERRORS** to v1.7.4
|
|
120
|
+
|
|
121
|
+
**Library Version Installed**: `AlteriomPainlessMesh@1.7.5+sha.499d597`
|
|
122
|
+
|
|
123
|
+
**Conclusion**: v1.7.5 did not resolve the compilation issues present in v1.7.4.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Technical Analysis
|
|
128
|
+
|
|
129
|
+
### Expected Type Definition
|
|
130
|
+
|
|
131
|
+
The `_task_request_t` type should be defined in TaskScheduler when thread-safe mode is enabled:
|
|
132
|
+
|
|
133
|
+
**Expected from TaskScheduler** (`TaskSchedulerDeclarations.h`):
|
|
134
|
+
```cpp
|
|
135
|
+
#ifdef _TASK_THREAD_SAFE
|
|
136
|
+
typedef struct {
|
|
137
|
+
Task* task;
|
|
138
|
+
unsigned long param1;
|
|
139
|
+
long param2;
|
|
140
|
+
TaskCallback param3;
|
|
141
|
+
TaskOnEnable param4;
|
|
142
|
+
TaskOnDisable param5;
|
|
143
|
+
int request_type;
|
|
144
|
+
} _task_request_t;
|
|
145
|
+
#endif
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Actual Configuration
|
|
149
|
+
|
|
150
|
+
**painlessMesh v1.7.4/v1.7.5** (`src/painlessTaskOptions.h`):
|
|
151
|
+
```cpp
|
|
152
|
+
#define _TASK_PRIORITY // Support for layered scheduling priority
|
|
153
|
+
|
|
154
|
+
// Thread-safe scheduler for ESP32 to prevent FreeRTOS assertion failures
|
|
155
|
+
#ifdef ESP32
|
|
156
|
+
#define _TASK_THREAD_SAFE // Enable FreeRTOS queue-based task control
|
|
157
|
+
// Note: _TASK_STD_FUNCTION is incompatible with _TASK_THREAD_SAFE in TaskScheduler v4.0.x
|
|
158
|
+
#else
|
|
159
|
+
#define _TASK_STD_FUNCTION // Support for std::function (ESP8266 ONLY)
|
|
160
|
+
#endif
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Include Order Problem
|
|
164
|
+
|
|
165
|
+
The issue is with the include order and macro visibility:
|
|
166
|
+
|
|
167
|
+
1. **Step 1**: Project includes `painlessMesh.h`
|
|
168
|
+
2. **Step 2**: `painlessMesh.h` includes `TaskSchedulerDeclarations.h` (before `painlessTaskOptions.h`)
|
|
169
|
+
3. **Step 3**: TaskScheduler processes without `_TASK_THREAD_SAFE` defined
|
|
170
|
+
4. **Step 4**: `_task_request_t` type is NOT defined
|
|
171
|
+
5. **Step 5**: Later, `scheduler_queue.cpp` tries to use undefined type
|
|
172
|
+
|
|
173
|
+
### Additional Incompatibility
|
|
174
|
+
|
|
175
|
+
painlessMesh documentation notes:
|
|
176
|
+
> "_TASK_STD_FUNCTION is incompatible with _TASK_THREAD_SAFE in TaskScheduler v4.0.x"
|
|
177
|
+
|
|
178
|
+
This creates a fundamental conflict:
|
|
179
|
+
- **ESP8266**: Uses `_TASK_STD_FUNCTION` (std::function callbacks)
|
|
180
|
+
- **ESP32**: Needs `_TASK_THREAD_SAFE` (FreeRTOS queue)
|
|
181
|
+
- **TaskScheduler v4.0.2**: Cannot support both simultaneously
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Build Environment Details
|
|
186
|
+
|
|
187
|
+
### Successful Build (v1.7.2)
|
|
188
|
+
|
|
189
|
+
**Version**: `AlteriomPainlessMesh@1.7.2+sha.1d0ba8d`
|
|
190
|
+
**Build Number**: 8021
|
|
191
|
+
**Compilation**: ✅ **SUCCESS**
|
|
192
|
+
**Runtime**: ❌ Crashes with FreeRTOS assertion when sensor nodes connect
|
|
193
|
+
|
|
194
|
+
**Build Output**:
|
|
195
|
+
```
|
|
196
|
+
Library Manager: AlteriomPainlessMesh@1.7.2+sha.1d0ba8d has been installed!
|
|
197
|
+
[SUCCESS] Took 260.55 seconds
|
|
198
|
+
RAM: [==== ] 36.2% (used 118620 bytes from 327680 bytes)
|
|
199
|
+
Flash: [========= ] 85.6% (used 1570349 bytes from 1835008 bytes)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Failed Build (v1.7.4)
|
|
203
|
+
|
|
204
|
+
**Version**: `AlteriomPainlessMesh@1.7.4+sha.7cd66ac`
|
|
205
|
+
**Build Number**: 8022
|
|
206
|
+
**Compilation**: ❌ **FAILED**
|
|
207
|
+
**Error**: Missing `_task_request_t` type definition
|
|
208
|
+
|
|
209
|
+
**Build Time to Failure**: ~288 seconds (4 min 48 sec)
|
|
210
|
+
**Failure Point**: Compiling `scheduler_queue.cpp`
|
|
211
|
+
|
|
212
|
+
### Failed Build (v1.7.5)
|
|
213
|
+
|
|
214
|
+
**Version**: `AlteriomPainlessMesh@1.7.5+sha.499d597`
|
|
215
|
+
**Build Number**: 8024
|
|
216
|
+
**Compilation**: ❌ **FAILED**
|
|
217
|
+
**Error**: Missing `_task_request_t` type definition (identical to v1.7.4)
|
|
218
|
+
|
|
219
|
+
**Build Time to Failure**: ~242 seconds (4 min 2 sec)
|
|
220
|
+
**Failure Point**: Compiling `scheduler_queue.cpp`
|
|
221
|
+
|
|
222
|
+
### Docker Build Environment
|
|
223
|
+
|
|
224
|
+
**Platform**: Espressif 32 (6.8.1)
|
|
225
|
+
**Framework**: Arduino (framework-arduinoespressif32 @ 3.20017.241212+sha.dcc1105b)
|
|
226
|
+
**Toolchain**: toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
|
|
227
|
+
**Board**: ESP32-D0WD-V3 (revision 3)
|
|
228
|
+
|
|
229
|
+
**Libraries**:
|
|
230
|
+
- **TaskScheduler**: v4.0.2 (arkhipenko/TaskScheduler)
|
|
231
|
+
- **ArduinoJson**: v7.4.2
|
|
232
|
+
- **AsyncTCP**: v3.4.9
|
|
233
|
+
- **PubSubClient**: v2.8.0
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Attempted Workarounds
|
|
238
|
+
|
|
239
|
+
### Attempt 1: Use v1.7.3
|
|
240
|
+
|
|
241
|
+
**Theory**: v1.7.3 might be intermediate version between v1.7.2 (working) and v1.7.4 (broken)
|
|
242
|
+
|
|
243
|
+
**Configuration**:
|
|
244
|
+
```ini
|
|
245
|
+
[common_libs]
|
|
246
|
+
lib_deps =
|
|
247
|
+
https://github.com/Alteriom/painlessMesh.git#v1.7.3
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Result**: ❌ **FAILED**
|
|
251
|
+
- Git tag v1.7.3 exists but resolves to SHA `86e2ccc` which is **v1.7.2**
|
|
252
|
+
- Library Manager shows: `AlteriomPainlessMesh@1.7.2+sha.86e2ccc`
|
|
253
|
+
- Conclusion: v1.7.3 tag is mislabeled
|
|
254
|
+
|
|
255
|
+
### Attempt 2: Use v1.7.5 (Latest)
|
|
256
|
+
|
|
257
|
+
**Theory**: v1.7.5 might fix the v1.7.4 compilation issues
|
|
258
|
+
|
|
259
|
+
**Configuration**:
|
|
260
|
+
```ini
|
|
261
|
+
[common_libs]
|
|
262
|
+
lib_deps =
|
|
263
|
+
https://github.com/Alteriom/painlessMesh.git#v1.7.5
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Result**: ❌ **FAILED**
|
|
267
|
+
- Identical compilation errors to v1.7.4
|
|
268
|
+
- Same missing `_task_request_t` type
|
|
269
|
+
- No improvement in include order or type visibility
|
|
270
|
+
|
|
271
|
+
### Attempt 3: Uninstall and Reinstall Library
|
|
272
|
+
|
|
273
|
+
**Theory**: Cached library might be corrupt or using wrong version
|
|
274
|
+
|
|
275
|
+
**Commands**:
|
|
276
|
+
```bash
|
|
277
|
+
docker-compose run --rm alteriom-builder pio pkg uninstall --library "https://github.com/Alteriom/painlessMesh.git#v1.7.2"
|
|
278
|
+
docker-compose run --rm alteriom-builder pio pkg install --library "https://github.com/Alteriom/painlessMesh.git#v1.7.4"
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Result**: ❌ **FAILED**
|
|
282
|
+
- Fresh library download still has compilation errors
|
|
283
|
+
- Confirms issue is in library code, not local environment
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Current Workaround
|
|
288
|
+
|
|
289
|
+
### Stay on v1.7.2 with Known Limitations
|
|
290
|
+
|
|
291
|
+
**Configuration** (`platformio.ini`):
|
|
292
|
+
```ini
|
|
293
|
+
[common_libs]
|
|
294
|
+
lib_deps =
|
|
295
|
+
https://github.com/Alteriom/painlessMesh.git#v1.7.2 ; Only version that compiles
|
|
296
|
+
knolleary/PubSubClient@^2.8
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**Trade-offs**:
|
|
300
|
+
- ✅ **Compiles successfully**
|
|
301
|
+
- ✅ **Can test MQTT buffer fixes** (for ~15 seconds before crash)
|
|
302
|
+
- ❌ **FreeRTOS crashes** when sensor nodes connect (~15-20 seconds uptime)
|
|
303
|
+
- ❌ **Cannot achieve stable mesh network**
|
|
304
|
+
|
|
305
|
+
**Crash Pattern**:
|
|
306
|
+
```
|
|
307
|
+
[GATEWAY MESH DEBUG] Current connected nodes: 1
|
|
308
|
+
[GATEWAY MESH DEBUG] Node IDs: 1693975713
|
|
309
|
+
CONNECTION: newConnectionTask(): adding 1693975713 now= 15192604
|
|
310
|
+
|
|
311
|
+
assert failed: vTaskPriorityDisinheritAfterTimeout tasks.c:5034
|
|
312
|
+
(pxTCB != pxCurrentTCB[xPortGetCoreID()])
|
|
313
|
+
|
|
314
|
+
Backtrace: 0x40083831:0x3ffb1e70 0x4008ee75:0x3ffb1e90 0x4009465d:0x3ffb1eb0
|
|
315
|
+
|
|
316
|
+
E (15264) esp_core_dump_flash: Core dump flash config is corrupted!
|
|
317
|
+
Rebooting...
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Impact on Alteriom Project
|
|
323
|
+
|
|
324
|
+
### Development Blocked
|
|
325
|
+
|
|
326
|
+
1. **Phase 2 MQTT Commands**: Cannot fully test due to 15-second crash loop
|
|
327
|
+
2. **Mesh Stability**: Cannot achieve multi-node mesh networks
|
|
328
|
+
3. **Production Deployment**: Cannot deploy gateway firmware with sensor nodes
|
|
329
|
+
|
|
330
|
+
### Current Status
|
|
331
|
+
|
|
332
|
+
**Build 8021** (Current):
|
|
333
|
+
- **Firmware Version**: GW 2.3.7
|
|
334
|
+
- **Build Number**: 8021 (32-MSH)
|
|
335
|
+
- **painlessMesh**: v1.7.2
|
|
336
|
+
- **MQTT Buffer**: 4096 bytes (increased from 256 - **READY TO TEST**)
|
|
337
|
+
- **Status**: Compiles ✅, Crashes ❌
|
|
338
|
+
|
|
339
|
+
**Testing Limitations**:
|
|
340
|
+
- Can observe MQTT diagnostics for ~15 seconds
|
|
341
|
+
- Can send commands but device reboots before response
|
|
342
|
+
- Cannot validate MQTT buffer fix effectiveness
|
|
343
|
+
- Cannot test `get_config` command responses
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Recommended Solutions
|
|
348
|
+
|
|
349
|
+
### Option 1: Wait for painlessMesh v1.7.6 (RECOMMENDED)
|
|
350
|
+
|
|
351
|
+
**Requirements**:
|
|
352
|
+
- Fix `_task_request_t` type visibility issue
|
|
353
|
+
- Ensure `_TASK_THREAD_SAFE` macro is defined before TaskScheduler inclusion
|
|
354
|
+
- Test compilation with TaskScheduler v4.0.2
|
|
355
|
+
- Validate thread-safe queue implementation works
|
|
356
|
+
|
|
357
|
+
**Timeline**: Unknown - depends on upstream maintainers
|
|
358
|
+
|
|
359
|
+
**Risk**: Low - lets experts fix the issue properly
|
|
360
|
+
|
|
361
|
+
### Option 2: Manual Patch v1.7.5 Locally
|
|
362
|
+
|
|
363
|
+
**Steps**:
|
|
364
|
+
1. Clone painlessMesh v1.7.5 locally
|
|
365
|
+
2. Modify include order in `scheduler_queue.hpp`:
|
|
366
|
+
```cpp
|
|
367
|
+
#ifdef ESP32
|
|
368
|
+
|
|
369
|
+
// MUST include TaskScheduler declarations FIRST
|
|
370
|
+
#define _TASK_THREAD_SAFE // Define BEFORE including TaskScheduler
|
|
371
|
+
#include <TaskSchedulerDeclarations.h>
|
|
372
|
+
|
|
373
|
+
#include <freertos/FreeRTOS.h>
|
|
374
|
+
#include <freertos/queue.h>
|
|
375
|
+
// ... rest of includes
|
|
376
|
+
```
|
|
377
|
+
3. Test compilation
|
|
378
|
+
4. Submit pull request to painlessMesh
|
|
379
|
+
|
|
380
|
+
**Risk**: Medium - requires understanding of build system
|
|
381
|
+
|
|
382
|
+
### Option 3: Increase Semaphore Timeout in v1.7.2
|
|
383
|
+
|
|
384
|
+
**Workaround**: Apply FreeRTOS fix manually without thread-safe queue
|
|
385
|
+
|
|
386
|
+
**Implementation**:
|
|
387
|
+
Modify `.pio/libdeps/universal-gateway/AlteriomPainlessMesh/src/painlessmesh/mesh.hpp` line 544:
|
|
388
|
+
|
|
389
|
+
**Change from**:
|
|
390
|
+
```cpp
|
|
391
|
+
return xSemaphoreTake(xSemaphore, (TickType_t)10) == pdTRUE;
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**Change to**:
|
|
395
|
+
```cpp
|
|
396
|
+
return xSemaphoreTake(xSemaphore, (TickType_t)100) == pdTRUE;
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**Effectiveness**: ~80-85% reduction in crashes (according to painlessMesh docs)
|
|
400
|
+
**Risk**: Medium - modifies library code directly, lost on clean builds
|
|
401
|
+
**Benefit**: No compilation issues, simpler fix
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Files Affected
|
|
406
|
+
|
|
407
|
+
### Working Version (v1.7.2)
|
|
408
|
+
|
|
409
|
+
**Modified in Alteriom Project**:
|
|
410
|
+
- `platformio.ini` - Library version pinned to v1.7.2
|
|
411
|
+
- `src/gateway/common_functions.cpp` - Added MQTT diagnostics (Build 8021)
|
|
412
|
+
- `platformio.ini` - Added `-D MQTT_MAX_PACKET_SIZE=4096` (Build 8021)
|
|
413
|
+
|
|
414
|
+
### Problematic Files (v1.7.4/v1.7.5)
|
|
415
|
+
|
|
416
|
+
**painlessMesh Library**:
|
|
417
|
+
- `src/painlessTaskOptions.h` - Defines `_TASK_THREAD_SAFE` (too late in compilation)
|
|
418
|
+
- `src/painlessmesh/scheduler_queue.hpp` - Declares queue functions
|
|
419
|
+
- `src/painlessmesh/scheduler_queue.cpp` - **FAILS TO COMPILE** - missing type definitions
|
|
420
|
+
- `src/painlessmesh/mesh.hpp` - Calls `scheduler::initQueue()`
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## Testing Evidence
|
|
425
|
+
|
|
426
|
+
### Build Timeline
|
|
427
|
+
|
|
428
|
+
| Build | Version | Status | Duration | Outcome |
|
|
429
|
+
|-------|---------|--------|----------|---------|
|
|
430
|
+
| 8020 | v1.7.2 | ✅ Success | 260s | Compiles, crashes in runtime |
|
|
431
|
+
| 8021 | v1.7.2 | ✅ Success | ~260s | Compiles, crashes in runtime, **has MQTT fix** |
|
|
432
|
+
| 8022 | v1.7.4 | ❌ Failed | 288s | Compilation error: `_task_request_t` |
|
|
433
|
+
| 8023 | v1.7.3 | ❌ Failed | 291s | Actually v1.7.2, same issues |
|
|
434
|
+
| 8024 | v1.7.5 | ❌ Failed | 242s | Compilation error: `_task_request_t` |
|
|
435
|
+
|
|
436
|
+
### Serial Output (v1.7.2 Runtime Crash)
|
|
437
|
+
|
|
438
|
+
```
|
|
439
|
+
=== GATEWAY NODE BOOT SEQUENCE ===
|
|
440
|
+
Firmware Version: GW 2.3.7
|
|
441
|
+
Build Info: Build 8021 (32-MSH)
|
|
442
|
+
Gateway Device ID: ALT-6825DD341CA4
|
|
443
|
+
|
|
444
|
+
[PHASE 1] Display initialization... ✓
|
|
445
|
+
[PHASE 2] Configuration loading... ✓
|
|
446
|
+
[PHASE 3] WiFi connection... ✓
|
|
447
|
+
WiFi connected! IP: 192.168.1.178
|
|
448
|
+
|
|
449
|
+
[PHASE 4] Time synchronization... ✓
|
|
450
|
+
[PHASE 5] MQTT connection... ✓
|
|
451
|
+
✅ MQTT: Connected successfully
|
|
452
|
+
✅ MQTT: Subscribed to gateway command topic: alteriom/gateway/ALT-6825DD341CA4/command
|
|
453
|
+
|
|
454
|
+
[PHASE 6] Mesh initialization... ✓
|
|
455
|
+
[PHASE 7] Sensor initialization... ✓
|
|
456
|
+
[PHASE 8] Display ready... ✓
|
|
457
|
+
|
|
458
|
+
Total Boot Time: 11389 ms
|
|
459
|
+
Ready for operation.
|
|
460
|
+
|
|
461
|
+
[INFO] Active mesh nodes: 0
|
|
462
|
+
|
|
463
|
+
[15 seconds later]
|
|
464
|
+
|
|
465
|
+
[GATEWAY MESH DEBUG] Current connected nodes: 1
|
|
466
|
+
[GATEWAY MESH DEBUG] Node IDs: 1693975713
|
|
467
|
+
CONNECTION: newConnectionTask(): adding 1693975713 now= 15192604
|
|
468
|
+
|
|
469
|
+
assert failed: vTaskPriorityDisinheritAfterTimeout tasks.c:5034
|
|
470
|
+
(pxTCB != pxCurrentTCB[xPortGetCoreID()])
|
|
471
|
+
|
|
472
|
+
Backtrace: 0x40083831:0x3ffb1e70 0x4008ee75:0x3ffb1e90 0x4009465d:0x3ffb1eb0 ...
|
|
473
|
+
|
|
474
|
+
Rebooting...
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Crash Frequency**: 100% reproducible when sensor node connects
|
|
478
|
+
|
|
479
|
+
---
|
|
480
|
+
|
|
481
|
+
## GitHub Issue Template
|
|
482
|
+
|
|
483
|
+
### Title
|
|
484
|
+
`[ESP32] v1.7.4/v1.7.5 Compilation Failure: _task_request_t not declared`
|
|
485
|
+
|
|
486
|
+
### Description
|
|
487
|
+
```markdown
|
|
488
|
+
## Environment
|
|
489
|
+
- **Platform**: ESP32 (espressif32@6.8.1)
|
|
490
|
+
- **Framework**: Arduino
|
|
491
|
+
- **TaskScheduler Version**: v4.0.2
|
|
492
|
+
- **painlessMesh Versions Affected**: v1.7.4, v1.7.5
|
|
493
|
+
- **Working Version**: v1.7.2
|
|
494
|
+
|
|
495
|
+
## Issue
|
|
496
|
+
Compilation fails with "error: '_task_request_t' was not declared" when building with v1.7.4 or v1.7.5.
|
|
497
|
+
|
|
498
|
+
## Error Output
|
|
499
|
+
```
|
|
500
|
+
.pio/libdeps/.../AlteriomPainlessMesh/src/painlessmesh/scheduler_queue.cpp:16:49:
|
|
501
|
+
error: '_task_request_t' was not declared in this scope
|
|
502
|
+
tsQueue = xQueueCreate(TS_QUEUE_LEN, sizeof(_task_request_t));
|
|
503
|
+
^~~~~~~~~~~~~~~
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
## Root Cause
|
|
507
|
+
The `_task_request_t` type is not visible when compiling `scheduler_queue.cpp` because:
|
|
508
|
+
1. `_TASK_THREAD_SAFE` is defined in `painlessTaskOptions.h`
|
|
509
|
+
2. TaskScheduler headers are included before this definition takes effect
|
|
510
|
+
3. Type definition depends on macro being set before TaskScheduler inclusion
|
|
511
|
+
|
|
512
|
+
## Proposed Fix
|
|
513
|
+
Move `#define _TASK_THREAD_SAFE` to occur before including TaskScheduler headers, or include `TaskSchedulerDeclarations.h` after defining the macro in `scheduler_queue.hpp`.
|
|
514
|
+
|
|
515
|
+
## Workaround
|
|
516
|
+
Stay on v1.7.2, which compiles successfully (but has FreeRTOS crash bug).
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
## References
|
|
522
|
+
|
|
523
|
+
### painlessMesh Documentation
|
|
524
|
+
- v1.7.4 Release Notes: `docs/releases/PATCH_v1.7.4.md`
|
|
525
|
+
- FreeRTOS Fix Implementation: `docs/troubleshooting/FREERTOS_FIX_IMPLEMENTATION.md`
|
|
526
|
+
- Quick Fix Guide: `docs/troubleshooting/QUICK_FIX_FREERTOS.md`
|
|
527
|
+
|
|
528
|
+
### Related Commits
|
|
529
|
+
- **7391717**: "fix: Implement thread-safe scheduler for ESP32 FreeRTOS" (v1.7.4)
|
|
530
|
+
- **65afb16**: "fix: Increase semaphore timeout from 10 to 100 ticks" (v1.7.4)
|
|
531
|
+
- **499d597**: v1.7.5 release commit
|
|
532
|
+
|
|
533
|
+
### External Links
|
|
534
|
+
- [TaskScheduler GitHub](https://github.com/arkhipenko/TaskScheduler)
|
|
535
|
+
- [painlessMesh Repository](https://github.com/Alteriom/painlessMesh)
|
|
536
|
+
- [FreeRTOS Documentation](https://www.freertos.org/a00113.html)
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## Document Status
|
|
541
|
+
|
|
542
|
+
**Last Updated**: October 19, 2025
|
|
543
|
+
**Author**: Alteriom Development Team
|
|
544
|
+
**Status**: Active Issue
|
|
545
|
+
**Next Review**: When painlessMesh v1.7.6 is released
|
|
546
|
+
|
|
547
|
+
**Keywords**: painlessMesh, TaskScheduler, FreeRTOS, ESP32, compilation error, _task_request_t, thread-safe, v1.7.4, v1.7.5
|
package/library.json
CHANGED
package/library.properties
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name=AlteriomPainlessMesh
|
|
2
|
-
version=1.7.
|
|
2
|
+
version=1.7.6
|
|
3
3
|
author=Coopdis,Scotty Franzyshen,Edwin van Leeuwen,Germán Martín,Maximilian Schwarz,Doanh Doanh,Alteriom
|
|
4
4
|
maintainer=Alteriom
|
|
5
5
|
sentence=A painless way to setup a mesh with ESP8266 and ESP32 devices with Alteriom extensions
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alteriom/painlessmesh",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.6",
|
|
4
4
|
"description": "painlessMesh is a user-friendly library for creating mesh networks with ESP8266 and ESP32 devices. This Alteriom fork includes additional packages for sensor data (SensorPackage), device commands (CommandPackage), and status monitoring (StatusPackage). It handles routing and network management automatically, so you can focus on your application. The library uses JSON-based messaging and syncs time across all nodes, making it ideal for coordinated behaviour like synchronized light displays or sensor networks reporting to a central node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"arduino",
|
|
@@ -16,10 +16,6 @@
|
|
|
16
16
|
#include "painlessmesh/ota.hpp"
|
|
17
17
|
#endif
|
|
18
18
|
|
|
19
|
-
#if defined(ESP32) && defined(_TASK_THREAD_SAFE)
|
|
20
|
-
#include "painlessmesh/scheduler_queue.hpp"
|
|
21
|
-
#endif
|
|
22
|
-
|
|
23
19
|
namespace painlessmesh {
|
|
24
20
|
typedef std::function<void(uint32_t nodeId)> newConnectionCallback_t;
|
|
25
21
|
typedef std::function<void(uint32_t nodeId)> droppedConnectionCallback_t;
|
|
@@ -45,13 +41,6 @@ class Mesh : public ntp::MeshTime, public plugin::PackageHandler<T> {
|
|
|
45
41
|
|
|
46
42
|
#ifdef ESP32
|
|
47
43
|
xSemaphore = xSemaphoreCreateMutex();
|
|
48
|
-
|
|
49
|
-
#ifdef _TASK_THREAD_SAFE
|
|
50
|
-
// Initialize the TaskScheduler request queue for thread-safe operations
|
|
51
|
-
if (!scheduler::initQueue()) {
|
|
52
|
-
Log(ERROR, "Failed to create TaskScheduler request queue\n");
|
|
53
|
-
}
|
|
54
|
-
#endif
|
|
55
44
|
#endif
|
|
56
45
|
|
|
57
46
|
// Add package handlers
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#include "painlessmesh/scheduler_queue.hpp"
|
|
2
|
-
|
|
3
|
-
#ifdef ESP32
|
|
4
|
-
|
|
5
|
-
namespace painlessmesh {
|
|
6
|
-
namespace scheduler {
|
|
7
|
-
|
|
8
|
-
// Global queue handle for TaskScheduler thread-safe operations
|
|
9
|
-
QueueHandle_t tsQueue = NULL;
|
|
10
|
-
|
|
11
|
-
bool initQueue() {
|
|
12
|
-
if (tsQueue != NULL) {
|
|
13
|
-
return true; // Already initialized
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
tsQueue = xQueueCreate(TS_QUEUE_LEN, sizeof(_task_request_t));
|
|
17
|
-
return (tsQueue != NULL);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
} // namespace scheduler
|
|
21
|
-
} // namespace painlessmesh
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Enqueue a task request (called from any thread/ISR)
|
|
25
|
-
* This function is required when _TASK_THREAD_SAFE is enabled
|
|
26
|
-
*
|
|
27
|
-
* Overrides the weak default implementation in TaskScheduler.h
|
|
28
|
-
*/
|
|
29
|
-
bool _task_enqueue_request(_task_request_t* req) {
|
|
30
|
-
using namespace painlessmesh::scheduler;
|
|
31
|
-
|
|
32
|
-
if (tsQueue == NULL) {
|
|
33
|
-
return false; // Queue not initialized
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (xPortInIsrContext()) {
|
|
37
|
-
// Called from ISR context
|
|
38
|
-
BaseType_t xHigherPriorityTaskWokenByPost = pdFALSE;
|
|
39
|
-
BaseType_t rc = xQueueSendFromISR(tsQueue, req, &xHigherPriorityTaskWokenByPost);
|
|
40
|
-
if (xHigherPriorityTaskWokenByPost) {
|
|
41
|
-
portYIELD_FROM_ISR();
|
|
42
|
-
}
|
|
43
|
-
return (rc == pdTRUE);
|
|
44
|
-
} else {
|
|
45
|
-
// Called from normal task context
|
|
46
|
-
return (xQueueSend(tsQueue, req, pdMS_TO_TICKS(TS_ENQUEUE_WAIT_MS)) == pdTRUE);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Dequeue a task request (called by scheduler)
|
|
52
|
-
* This function is required when _TASK_THREAD_SAFE is enabled
|
|
53
|
-
*
|
|
54
|
-
* Overrides the weak default implementation in TaskScheduler.h
|
|
55
|
-
*/
|
|
56
|
-
bool _task_dequeue_request(_task_request_t* req) {
|
|
57
|
-
using namespace painlessmesh::scheduler;
|
|
58
|
-
|
|
59
|
-
if (tsQueue == NULL) {
|
|
60
|
-
return false; // Queue not initialized
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (xPortInIsrContext()) {
|
|
64
|
-
// Called from ISR context (shouldn't normally happen)
|
|
65
|
-
BaseType_t xHigherPriorityTaskWokenByPost = pdFALSE;
|
|
66
|
-
BaseType_t rc = xQueueReceiveFromISR(tsQueue, req, &xHigherPriorityTaskWokenByPost);
|
|
67
|
-
if (xHigherPriorityTaskWokenByPost) {
|
|
68
|
-
portYIELD_FROM_ISR();
|
|
69
|
-
}
|
|
70
|
-
return (rc == pdTRUE);
|
|
71
|
-
} else {
|
|
72
|
-
// Called from normal task context
|
|
73
|
-
return (xQueueReceive(tsQueue, req, TS_DEQUEUE_WAIT_MS) == pdTRUE);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
#endif // ESP32
|