FastLED 3.10.9
Loading...
Searching...
No Matches

◆ legacyAsyncErrorProbe()

fl::json autoresearch::legacyAsyncErrorProbe ( const fl::json & args)
inline

Definition at line 183 of file AutoResearchLegacyAsyncErrors.h.

183 {
184 fl::json result = fl::json::object();
185#if AUTORESEARCH_LEGACY_OBSERVES_RMT4_FRAMES && FL_RMT4_ASYNC // ok platform specific - native and other-backend builds return an explicit unsupported result.
186 using namespace legacy_async_errors;
187 const fl::string mode = args["mode"].as_string().value_or("unavailable");
188 result.set("mode", mode);
189 const bool injected = mode == "task-allocation" ||
190 mode == "mutex-allocation" || mode == "install";
191 const bool recoveryMode = mode == "timeout" || mode == "invalid-batch";
192 if (mode != "unavailable" && mode != "setup" && !recoveryMode && !injected) {
193 result.set("success", false);
194 result.set("error", "Unknown legacy asynchronous failure fixture mode");
195 return result;
196 }
197 if (mode == "timeout" &&
198 (FASTLED_RMT4_TRANSMISSION_TIMEOUT_MS != 1 || !FL_RMT4_DIAGNOSTICS)) { // ok platform specific - this fixture requires RMT4-only worker diagnostics or fault-test configuration, with no neutral equivalent.
199 result.set("success", false);
200 result.set("error", "timeout fixture requires FASTLED_RMT4_TRANSMISSION_TIMEOUT_MS=1 and FL_RMT4_DIAGNOSTICS=1");
201 return result;
202 }
203 if (mode == "invalid-batch" && !FL_RMT4_DIAGNOSTICS) { // ok platform specific - this fixture requires RMT4-only worker diagnostics or fault-test configuration, with no neutral equivalent.
204 result.set("success", false);
205 result.set("error", "invalid-batch fixture requires FL_RMT4_DIAGNOSTICS=1");
206 return result;
207 }
208 if (!FastLED.wait(1000)) {
209 result.set("success", false);
210 result.set("error", "Existing output did not drain before fixture");
211 return result;
212 }
213 if (injected) {
214#if defined(FL_RMT4_FAULT_TEST) && FL_RMT4_FAULT_TEST == 1 // ok platform specific - injected failures require dedicated wrapper-linked test firmware.
215 return injectedFailureProbe(mode);
216#else
217 result.set("success", false);
218 result.set("error", "Requires FL_RMT4_FAULT_TEST=1 and the documented SDK linker wrappers");
219 return result;
220#endif
221 }
222 auto &manager = fl::RmtMemoryManager4::instance(); // ok platform specific - reserve and audit real RMT4 hardware blocks for exhaustion recovery; no neutral allocator exposes them.
223 const size_t baseline = manager.allocatedWords(); // ok platform specific - reserve and audit real RMT4 hardware blocks for exhaustion recovery; no neutral allocator exposes them.
224 auto frame = makeFrame(mode == "timeout" ? 4000 : 1);
225 if (!frame) {
226 result.set("success", false);
227 result.set("error", "Fixture frame allocation failed");
228 return result;
229 }
230 Observation observed;
231 bool recovered = false;
232 unsigned reserved = 0;
233 fl::u32 reservationMask = 0;
234 if (mode == "unavailable") {
235 FreeBlockReservations reservations(manager);
236 reserved = reservations.count();
237 reservationMask = reservations.mask();
238 fl::Rmt4AsyncDriver driver(fl::make_shared<fl::Rmt4PeripheralESP>()); // ok platform specific - construct an isolated RMT4 worker for backend-specific failure recovery, unavailable through the neutral factory.
239 observed = submit(driver, frame);
240 } else if (mode == "setup") {
241 // A missing real peripheral exercises the existing setup-failure path;
242 // no SDK return value or production behavior is replaced by a mock.
243 fl::Rmt4AsyncDriver driver{fl::shared_ptr<fl::detail::IRMT4Peripheral>()}; // ok platform specific - construct an isolated RMT4 worker for backend-specific failure recovery, unavailable through the neutral factory.
244 observed = submit(driver, frame);
245 } else {
246 fl::Rmt4AsyncDriver driver(fl::make_shared<fl::Rmt4PeripheralESP>()); // ok platform specific - construct an isolated RMT4 worker for backend-specific failure recovery, unavailable through the neutral factory.
247 if (mode == "invalid-batch") {
248 // The bridge rejects an unencodable strip this way. A subsequent
249 // valid strip must not erase that failure from the same batch.
250 driver.enqueue(fl::ChannelDataPtr());
251 }
252 observed = submit(driver, frame);
253 recovered = recoverySucceeded(driver);
254 }
255 const size_t after = manager.allocatedWords(); // ok platform specific - reserve and audit real RMT4 hardware blocks for exhaustion recovery; no neutral allocator exposes them.
256 bool reservationsRestored = true;
257 for (unsigned block = 0; block < 32; ++block) {
258 if (reservationMask & (fl::u32(1) << block)) {
259 const bool available = manager.tryReserveBlocks(static_cast<int>(block), 1); // ok platform specific - reserve and audit real RMT4 hardware blocks for exhaustion recovery; no neutral allocator exposes them.
260 reservationsRestored &= available;
261 if (available) { manager.releaseBlocks(static_cast<int>(block), 1); } // ok platform specific - reserve and audit real RMT4 hardware blocks for exhaustion recovery; no neutral allocator exposes them.
262 }
263 }
264 appendObservation(result, observed);
265 result.set("reservedFreeBlocks", static_cast<int>(reserved));
266 result.set("allocatedWordsBefore", static_cast<int>(baseline));
267 result.set("allocatedWordsAfter", static_cast<int>(after));
268 result.set("ledgerRestored", baseline == after);
269 result.set("fixtureReservationsRestored", reservationsRestored);
270 result.set("recoveryAttempted", recoveryMode);
271 result.set("recoveredOnSameDriver", recoveryMode && recovered);
272 result.set("success", observed.leasedAtSubmission &&
273 observed.releasedAutonomously && observed.errorReported &&
274 !observed.completionSucceeded && baseline == after &&
275 (mode != "timeout" ||
276 (observed.translatedBytes > 0 && observed.translatedBytes < frame->getSize())) &&
277 (mode != "invalid-batch" || observed.translatedBytes == 3) &&
278 reservationsRestored && (!recoveryMode || recovered));
279#else
280 (void)args;
281 result.set("success", false);
282 result.set("error", "Requires asynchronous classic ESP32 RMT4 output");
283#endif
284 return result;
285}
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
void wait() FL_NO_EXCEPT
Wait for all channel bus transmissions to complete.
static json object() FL_NO_EXCEPT
Definition json.h:864
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:423
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
int available() FL_NO_EXCEPT
corkscrew_args args
Definition old.h:149

References args, FastLED, fl::adl_barrier::make_shared(), and fl::json::object().

+ Here is the call graph for this function: