-
Notifications
You must be signed in to change notification settings - Fork 709
cam_hal: shrink ISR stack, silence spam, strip logs at low levels #765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
cam_hal: shrink ISR stack, silence spam, strip logs at low levels #765
Conversation
– prevents stack-overflow in cam_task The old cam_take() used recursion to retry if * no JPEG EOI was found or * a NULL frame pointer was returned (GDMA glitch on ESP32-S3). Under heavy loss conditions this could overflow the cam_task stack and reboot the whole system. * Re-wrote cam_take() as a single while-loop – stack depth is now constant and independent of retry count. * Added strict timeout tracking (`remaining = timeout - elapsed`); function can never block longer than the caller’s timeout. * ESP32-S3 only * capped GDMA reset storms to 3 attempts (`MAX_GDMA_RESETS`) * logs one “giving up” warning, then yields (`vTaskDelay(1)`) to avoid busy-spin after hardware is wedged. * Non-S3 targets * emit early `ESP_LOGW` when a NULL frame ever appears, then yield one tick per loop to prevent CPU thrash. * Maintained existing JPEG-EOI trimming and YUV→GRAY memcpy paths; behaviour unchanged on successful frames. * Inline comment links to esp32-camera commit 984999f / issue espressif#620 for future context.
and (2) over-reading the last 2 bytes Changes: * Store SOI as a 3-byte array (0xFF D8 FF) and use sizeof() everywhere. * Early-exit when length < 3 to avoid over-reading * calculate end index correctly, to avoid over-reading
If DMA returns a frame shorter than two bytes, the previous code did: dptr = inbuf + length - 2; which under-flows the pointer and produces undefined behaviour. Behaviour for valid frames (length ≥ 2) is unchanged; damaged or empty buffers are now discarded safely.
* Replace ESP_LOGx in ISRs/tight loops with CAM_WARN_THROTTLE(counter,msg) → uses ROM-resident ets_printf(); ~300 B less stack per hit. * At CONFIG_LOG_DEFAULT_LEVEL < 2 the macro compiles to a no-op, so *all* warning code is dropped from the binary. * First miss logs immediately, then every 100th; counter wraps at 10 000 (reset to 1 to skip the “first miss” banner after wrap). * New static uint16_t counters per call-site keep totals without globals. * Kconfig switch CAM_LOG_SPAM_EVERY_FRAME (=0) restores old per-frame debug. No functional change to capture path—just less stack, fewer cycles, smaller image, and a much quieter UART.
@turenkomv feel free to test. The goal here is to be less crashy without increasing the standard stack size. |
Without increasing the stack size, I’m getting a crash like this:
Increasing the stack size for framebuffer_task as shown here helps avoid the crash:
After that, the device runs stably — no more crashes — but still doesn’t receive any frames. |
thanks! Sorry for the delayed response. I'll wait for further development that I got the hardware, which arrived in my country today. So given the usual delay it should be here on monday. |
Description
Requires #758, #759 and #760 to be merged first, thus containing their commits here.
→ uses ROM-resident ets_printf(); ~300 B less stack per hit.
so all warning code is dropped from the binary.
(reset to 1 to skip the “first miss” banner after wrap).
No functional change to capture path—just less stack, fewer cycles,
smaller image, and a much quieter UART.
Related
Crashes reported by @turenkomv here due to excessive stack usage.
Checklist
Before submitting a Pull Request, please ensure the following: